Skip to main content
Glama

create_tasks

Creates ONE task (object) or up to 100 (array) — same parameter in both forms, like status of list_tasks. Fits any task, alone or in a batch: a single write, a single lock. Each task belongs to a block (or stays "No subject"). dueOn (YYYY-MM-DD) and dueText are not equivalent: only a date triggers "overdue". Assignees are resolved to the people of the project; an unknown designation is kept as is. id (optional) is a REPLAY key on the caller's side (ticket, import line): a second call carrying the SAME id on this project creates nothing more — the existing task is returned with alreadyExisted: true, not overwritten. The response returns tasks: [{id, title, url}] for each task of the batch, the GENERATED identifier included when you did not supply one — no need to re-read to learn it. url is the DIRECT LINK to the task (an arbitration opens the Arbitrations tab, preselected): it is the link the human follows for a reported task or arbitration. For a BATCH (at least two tasks), the response ALSO carries batchUrl: ONE single link to the whole batch, replacing N links (batchTitle = the sentence of the banner; beyond 60 tasks, batchUrlNote replaces the link). Assigning someone who will not ever have an OrgGen account (an external contact) is a NORMAL case, neither refused nor flagged as an anomaly. The response carries unreachableAssignees + note in two cases only: a label that designates no person of the schema, or — ONLY in a project that already links people to accounts — a person who is not linked. It is a FINDING, not a refusal. Migration from an external system (Linear, Jira, Notion…): externalSource/externalId (both together, or neither) display the provenance — id remains the ONLY replay key, the usual pattern for id is "<source>-<external-id>". dependsOn (ids of OTHER tasks of this project) BLOCKS this task — distinct from parentTaskId, which ORGANIZES without ever blocking. Each id must exist, including in this same batch if the referenced task appears earlier in the batch. An ARBITRATION (arbitrage, a question with options posed to a human) without cellId takes the block of its parent task (inheritedCellId on its entry); failing that it is born WITHOUT A SUBJECT — Arbitrations tab and Tasks view, no card — and the response SAYS so (arbitrageWithoutBlock + note). Without priority, an ARBITRATION raised under a parent task (parentTaskId) takes the priority of THAT task (inheritedPriority on its entry, absent when it is "normal") — a NAMED priority always wins, and it is modified afterwards through update_task. Linking to an ARCHIVED user story (US) is never refused (a US is sometimes reopened): the response SAYS so via archivedParents + archivedParentsNote — the created task will not appear by default in the Tasks view as long as the US stays archived. links (per task, up to 20) attaches its DELIVERABLES at creation; they are then added one by one through update_task.addLinks.

Input Schema

NameRequiredDescriptionDefault
tasksYesONE task (object) or UP TO 100 (array) — same parameter in both cases, like `status` of `list_tasks`. A single write, a single lock.
batchTitleNoBATCH form (at least two tasks): the sentence the view banner will display when the human opens `batchUrl`. Changes nothing about what is created. Maximum 120 characters.
expectedProjectIdNoUUID of the project targeted by THIS call. ACTUALLY targets this project instead of the session project. Refused without changing anything if access is not granted.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / tasks / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "arbitrage": {
      -        "description": "Turns this task into an ARBITRATION (a question with options posed to a human) — see `update_task.arbitrageAction` for the rest of the cycle (approval/challenge by the human, pick-up and closure by the agent). `cellId` omitted: the arbitration takes the block of its parent task (`parentTaskId`), otherwise it is born WITHOUT A SUBJECT (visible in the Arbitrations tab, on no card) — the response says so.",
      -        "properties": {
      -          "options": {
      -            "description": "The PRE-DEFINED answers — at least two, otherwise there is nothing to choose.",
      -            "items": {
      -              "additionalProperties": false,
      -              "properties": {
      -                "id": {
      -                  "description": "SHORT identifier of the option — cited by `choose`, and not displayed on its own.",
      -                  "maxLength": 100,
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "label": {
      -                  "description": "The text of the proposed answer.",
      -                  "maxLength": 300,
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "recommended": {
      -                  "anyOf": [
      -                    {
      -                      "additionalProperties": false,
      -                      "properties": {
      -                        "justification": {
      -                          "description": "Why this option is recommended — displayed next to it.",
      -                          "maxLength": 1000,
      -                          "minLength": 1,
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "justification"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "description": "Marks THIS option as the agent's recommendation. Omitted/`null` = no recommendation on this option (the normal case)."
      -                }
      -              },
      -              "required": [
      -                "id",
      -                "label"
      -              ],
      -              "type": "object"
      -            },
      -            "maxItems": 8,
      -            "minItems": 2,
      -            "type": "array"
      -          },
      -          "question": {
      -            "description": "The question posed to the human.",
      -            "maxLength": 2000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "selectionMode": {
      -            "description": "The human selection mode — `single` (one option only, the default) or `multiple` (checkboxes, several options possible). Set once and fixed afterwards.",
      -            "enum": [
      -              "single",
      -              "multiple"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "question",
      -          "options"
      -        ],
      -        "type": "object"
      -      },
      -      "assignees": {
      -        "description": "Assignees. An identifier or a name of a person of the project is RESOLVED; any other string is kept as is as an unresolved designation, not discarded.",
      -        "items": {
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 10,
      -        "type": "array"
      -      },
      -      "body": {
      -        "description": "Detailed note, optional.",
      -        "maxLength": 20000,
      -        "type": "string"
      -      },
      -      "cellId": {
      -        "description": "The block (cell) the task belongs to — RECOMMENDED in almost every case: a task without a cellId appears on NO card of the canvas, only in the Tasks view. A genuinely cross-cutting task with no single subject (e.g. \"prepare the monthly meeting\") goes without it. Omitted = a task with \"No subject\".",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "complexity": {
      -        "description": "RELATIVE order of magnitude in HUMAN TIME: xs = under an hour · s = a few hours · m = half a day to a day · l = a few days · xl = to SPLIT. It is estimated ahead of the pick-up of the work; it is an estimate, not a promise. No value = not estimated.",
      -        "enum": [
      -          "xs",
      -          "s",
      -          "m",
      -          "l",
      -          "xl"
      -        ],
      -        "type": "string"
      -      },
      -      "dependsOn": {
      -        "description": "Ids of OTHER tasks of this project that BLOCK this one (distinct from `parentTaskId`, which ORGANIZES without ever blocking). Each id must exist in this project — including in this SAME batch, if the referenced task appears earlier in the array. Omitted = no dependency. Distinct from `status: 'blocked'` (a manual action, independent): blocking BY DEPENDENCY is read via `list_tasks({fields:['dependsOn','openDependencyCount']})` or the `executable` filter.",
      -        "items": {
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 50,
      -        "type": "array"
      -      },
      -      "dueOn": {
      -        "description": "DATED due date (YYYY-MM-DD). Only a date makes \"overdue\" appear.",
      -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -        "type": "string"
      -      },
      -      "dueText": {
      -        "description": "Due date as free text (\"end of the week\"). Kept as is and displayed, but it triggers NO overdue calculation: `dueOn` carries the date when it is known.",
      -        "maxLength": 200,
      -        "type": "string"
      -      },
      -      "externalId": {
      -        "description": "The identifier of this task IN the originating system (e.g. \"ENG-1234\"). Goes in pair with `externalSource`, in every case.",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "externalSource": {
      -        "description": "The system this task comes from (e.g. \"linear\", \"jira\", \"notion\"). Displayed provenance — does not replace `id` as the idempotence key. Goes in pair with `externalId`, in every case.",
      -        "maxLength": 60,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Identifier supplied by the caller — a key on the external system's side (ticket, import line, an agent's replay key). Omitted = generated by OrgGen (tk_...). If this project already holds a task with this identifier, NOTHING is written for it: it is returned as is (alreadyExisted: true) — a replayed call does not duplicate, and different content on the second call does not overwrite the first. Migration from an external system: the usual pattern is `\"<source>-<external-id>\"` (e.g. `\"linear-ENG-1234\"`) — THIS field carries the idempotence, `externalSource`/`externalId` below only display the provenance.",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "labels": {
      -        "items": {
      -          "maxLength": 60,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 20,
      -        "type": "array"
      -      },
      -      "links": {
      -        "description": "The DELIVERABLES of this task (at most 20) — commit, pull request, deployment, run, document. They are then ADDED one by one through `update_task.addLinks`, not by replacing the list.",
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "documentId": {
      -              "description": "For the `document` type ONLY: the identifier of a document of the project that YOU can read (`list_documents`).",
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "key": {
      -              "description": "Your STABLE key for this deliverable (e.g. `pr-482`): replaying an addition with the same key does not duplicate it, it UPDATES it (this is how you move a PR from `open` to `merged`: a `key` and a `state` are then enough, without repeating the URL). Without a key, the URL (normalized), then `(type, ref)`, designate the entry.",
      -              "maxLength": 255,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "description": "Short displayed label.",
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "ref": {
      -              "description": "Short reference displayed in monospace (sha, PR number, run identifier).",
      -              "maxLength": 80,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "state": {
      -              "description": "The state YOU DECLARE, true at the time of the call — OrgGen never verifies it, the human sees \"declared by the agent\".",
      -              "enum": [
      -                "open",
      -                "merged",
      -                "closed",
      -                "succeeded",
      -                "failed",
      -                "superseded"
      -              ],
      -              "type": "string"
      -            },
      -            "type": {
      -              "description": "The kind of deliverable — closed enumeration.",
      -              "enum": [
      -                "commit",
      -                "pull_request",
      -                "deployment",
      -                "run",
      -                "document",
      -                "other"
      -              ],
      -              "type": "string"
      -            },
      -            "url": {
      -              "description": "ABSOLUTE http(s) address, without embedded username or password. OrgGen never opens it: it is only displayed.",
      -              "maxLength": 2048,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "type"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 20,
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "parentTaskId": {
      -        "description": "Links this task to its parent grouping (\"Part of\") — another task of this project WITHOUT `parentTaskId`, a user story (US) — of which it becomes a SUBTASK. The epic, on the other hand, is the BLOCK (`cellId`): the parent task is never the epic. Omitted = a top-level task (a US). Depth is limited to TWO levels: the target cannot already be a subtask itself. In a BATCH, the target can be created in the SAME call if it appears earlier in the array (with an explicit `id`).",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "priority": {
      -        "enum": [
      -          "urgent",
      -          "high",
      -          "normal",
      -          "low"
      -        ],
      -        "type": "string"
      -      },
      -      "status": {
      -        "enum": [
      -          "todo",
      -          "doing",
      -          "done",
      -          "blocked"
      -        ],
      -        "type": "string"
      -      },
      -      "title": {
      -        "description": "The task label, on one line.",
      -        "maxLength": 500,
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "title"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "items": {
      -      "additionalProperties": false,
      -      "properties": {
      -        "arbitrage": {
      -          "description": "Turns this task into an ARBITRATION (a question with options posed to a human) — see `update_task.arbitrageAction` for the rest of the cycle (approval/challenge by the human, pick-up and closure by the agent). `cellId` omitted: the arbitration takes the block of its parent task (`parentTaskId`), otherwise it is born WITHOUT A SUBJECT (visible in the Arbitrations tab, on no card) — the response says so.",
      -          "properties": {
      -            "options": {
      -              "description": "The PRE-DEFINED answers — at least two, otherwise there is nothing to choose.",
      -              "items": {
      -                "additionalProperties": false,
      -                "properties": {
      -                  "id": {
      -                    "description": "SHORT identifier of the option — cited by `choose`, and not displayed on its own.",
      -                    "maxLength": 100,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "label": {
      -                    "description": "The text of the proposed answer.",
      -                    "maxLength": 300,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "recommended": {
      -                    "anyOf": [
      -                      {
      -                        "additionalProperties": false,
      -                        "properties": {
      -                          "justification": {
      -                            "description": "Why this option is recommended — displayed next to it.",
      -                            "maxLength": 1000,
      -                            "minLength": 1,
      -                            "type": "string"
      -                          }
      -                        },
      -                        "required": [
      -                          "justification"
      -                        ],
      -                        "type": "object"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "Marks THIS option as the agent's recommendation. Omitted/`null` = no recommendation on this option (the normal case)."
      -                  }
      -                },
      -                "required": [
      -                  "id",
      -                  "label"
      -                ],
      -                "type": "object"
      -              },
      -              "maxItems": 8,
      -              "minItems": 2,
      -              "type": "array"
      -            },
      -            "question": {
      -              "description": "The question posed to the human.",
      -              "maxLength": 2000,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "selectionMode": {
      -              "description": "The human selection mode — `single` (one option only, the default) or `multiple` (checkboxes, several options possible). Set once and fixed afterwards.",
      -              "enum": [
      -                "single",
      -                "multiple"
      -              ],
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "question",
      -            "options"
      -          ],
      -          "type": "object"
      -        },
      -        "assignees": {
      -          "description": "Assignees. An identifier or a name of a person of the project is RESOLVED; any other string is kept as is as an unresolved designation, not discarded.",
      -          "items": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 10,
      -          "type": "array"
      -        },
      -        "body": {
      -          "description": "Detailed note, optional.",
      -          "maxLength": 20000,
      -          "type": "string"
      -        },
      -        "cellId": {
      -          "description": "The block (cell) the task belongs to — RECOMMENDED in almost every case: a task without a cellId appears on NO card of the canvas, only in the Tasks view. A genuinely cross-cutting task with no single subject (e.g. \"prepare the monthly meeting\") goes without it. Omitted = a task with \"No subject\".",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "complexity": {
      -          "description": "RELATIVE order of magnitude in HUMAN TIME: xs = under an hour · s = a few hours · m = half a day to a day · l = a few days · xl = to SPLIT. It is estimated ahead of the pick-up of the work; it is an estimate, not a promise. No value = not estimated.",
      -          "enum": [
      -            "xs",
      -            "s",
      -            "m",
      -            "l",
      -            "xl"
      -          ],
      -          "type": "string"
      -        },
      -        "dependsOn": {
      -          "description": "Ids of OTHER tasks of this project that BLOCK this one (distinct from `parentTaskId`, which ORGANIZES without ever blocking). Each id must exist in this project — including in this SAME batch, if the referenced task appears earlier in the array. Omitted = no dependency. Distinct from `status: 'blocked'` (a manual action, independent): blocking BY DEPENDENCY is read via `list_tasks({fields:['dependsOn','openDependencyCount']})` or the `executable` filter.",
      -          "items": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 50,
      -          "type": "array"
      -        },
      -        "dueOn": {
      -          "description": "DATED due date (YYYY-MM-DD). Only a date makes \"overdue\" appear.",
      -          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -          "type": "string"
      -        },
      -        "dueText": {
      -          "description": "Due date as free text (\"end of the week\"). Kept as is and displayed, but it triggers NO overdue calculation: `dueOn` carries the date when it is known.",
      -          "maxLength": 200,
      -          "type": "string"
      -        },
      -        "externalId": {
      -          "description": "The identifier of this task IN the originating system (e.g. \"ENG-1234\"). Goes in pair with `externalSource`, in every case.",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "externalSource": {
      -          "description": "The system this task comes from (e.g. \"linear\", \"jira\", \"notion\"). Displayed provenance — does not replace `id` as the idempotence key. Goes in pair with `externalId`, in every case.",
      -          "maxLength": 60,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "id": {
      -          "description": "Identifier supplied by the caller — a key on the external system's side (ticket, import line, an agent's replay key). Omitted = generated by OrgGen (tk_...). If this project already holds a task with this identifier, NOTHING is written for it: it is returned as is (alreadyExisted: true) — a replayed call does not duplicate, and different content on the second call does not overwrite the first. Migration from an external system: the usual pattern is `\"<source>-<external-id>\"` (e.g. `\"linear-ENG-1234\"`) — THIS field carries the idempotence, `externalSource`/`externalId` below only display the provenance.",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "labels": {
      -          "items": {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 20,
      -          "type": "array"
      -        },
      -        "links": {
      -          "description": "The DELIVERABLES of this task (at most 20) — commit, pull request, deployment, run, document. They are then ADDED one by one through `update_task.addLinks`, not by replacing the list.",
      -          "items": {
      -            "additionalProperties": false,
      -            "properties": {
      -              "documentId": {
      -                "description": "For the `document` type ONLY: the identifier of a document of the project that YOU can read (`list_documents`).",
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "key": {
      -                "description": "Your STABLE key for this deliverable (e.g. `pr-482`): replaying an addition with the same key does not duplicate it, it UPDATES it (this is how you move a PR from `open` to `merged`: a `key` and a `state` are then enough, without repeating the URL). Without a key, the URL (normalized), then `(type, ref)`, designate the entry.",
      -                "maxLength": 255,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "description": "Short displayed label.",
      -                "maxLength": 120,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "ref": {
      -                "description": "Short reference displayed in monospace (sha, PR number, run identifier).",
      -                "maxLength": 80,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "state": {
      -                "description": "The state YOU DECLARE, true at the time of the call — OrgGen never verifies it, the human sees \"declared by the agent\".",
      -                "enum": [
      -                  "open",
      -                  "merged",
      -                  "closed",
      -                  "succeeded",
      -                  "failed",
      -                  "superseded"
      -                ],
      -                "type": "string"
      -              },
      -              "type": {
      -                "description": "The kind of deliverable — closed enumeration.",
      -                "enum": [
      -                  "commit",
      -                  "pull_request",
      -                  "deployment",
      -                  "run",
      -                  "document",
      -                  "other"
      -                ],
      -                "type": "string"
      -              },
      -              "url": {
      -                "description": "ABSOLUTE http(s) address, without embedded username or password. OrgGen never opens it: it is only displayed.",
      -                "maxLength": 2048,
      -                "minLength": 1,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          "maxItems": 20,
      -          "minItems": 1,
      -          "type": "array"
      -        },
      -        "parentTaskId": {
      -          "description": "Links this task to its parent grouping (\"Part of\") — another task of this project WITHOUT `parentTaskId`, a user story (US) — of which it becomes a SUBTASK. The epic, on the other hand, is the BLOCK (`cellId`): the parent task is never the epic. Omitted = a top-level task (a US). Depth is limited to TWO levels: the target cannot already be a subtask itself. In a BATCH, the target can be created in the SAME call if it appears earlier in the array (with an explicit `id`).",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "priority": {
      -          "enum": [
      -            "urgent",
      -            "high",
      -            "normal",
      -            "low"
      -          ],
      -          "type": "string"
      -        },
      -        "status": {
      -          "enum": [
      -            "todo",
      -            "doing",
      -            "done",
      -            "blocked"
      -          ],
      -          "type": "string"
      -        },
      -        "title": {
      -          "description": "The task label, on one line.",
      -          "maxLength": 500,
      -          "minLength": 1,
      -          "type": "string"
      -        }
      -      },
      -      "required": [
      -        "title"
      -      ],
      -      "type": "object"
      -    },
      -    "maxItems": 100,
      -    "minItems": 1,
      -    "type": "array"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "arbitrage": {
      +        "description": "Turns this task into an ARBITRATION (a question with options posed to a human) — see `update_task.arbitrageAction` for the rest of the cycle (approval/challenge by the human, pick-up and closure by the agent). `cellId` omitted: the arbitration takes the block of its parent task (`parentTaskId`), otherwise it is born WITHOUT A SUBJECT (visible in the Arbitrations tab, on no card) — the response says so.",
      +        "properties": {
      +          "options": {
      +            "description": "The PRE-DEFINED answers — at least two, otherwise there is nothing to choose.",
      +            "items": {
      +              "additionalProperties": false,
      +              "properties": {
      +                "id": {
      +                  "description": "SHORT identifier of the option — cited by `choose`, and not displayed on its own.",
      +                  "maxLength": 100,
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "label": {
      +                  "description": "The text of the proposed answer.",
      +                  "maxLength": 300,
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "recommended": {
      +                  "anyOf": [
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "justification": {
      +                          "description": "Why this option is recommended — displayed next to it.",
      +                          "maxLength": 1000,
      +                          "minLength": 1,
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "justification"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "Marks THIS option as the agent's recommendation. Omitted/`null` = no recommendation on this option (the normal case)."
      +                }
      +              },
      +              "required": [
      +                "id",
      +                "label"
      +              ],
      +              "type": "object"
      +            },
      +            "maxItems": 8,
      +            "minItems": 2,
      +            "type": "array"
      +          },
      +          "question": {
      +            "description": "The question posed to the human.",
      +            "maxLength": 2000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "selectionMode": {
      +            "description": "The human selection mode — `single` (one option only, the default) or `multiple` (checkboxes, several options possible). Set once and fixed afterwards.",
      +            "enum": [
      +              "single",
      +              "multiple"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "question",
      +          "options"
      +        ],
      +        "type": "object"
      +      },
      +      "assignees": {
      +        "description": "Assignees. An identifier or a name of a person of the project is RESOLVED; any other string is kept as is as an unresolved designation, not discarded.",
      +        "items": {
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 10,
      +        "type": "array"
      +      },
      +      "body": {
      +        "description": "Detailed note, optional.",
      +        "maxLength": 20000,
      +        "type": "string"
      +      },
      +      "cellId": {
      +        "description": "The block (cell) the task belongs to — RECOMMENDED in almost every case: a task without a cellId appears on NO card of the canvas, only in the Tasks view. A genuinely cross-cutting task with no single subject (e.g. \"prepare the monthly meeting\") goes without it. Omitted = a task with \"No subject\".",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "complexity": {
      +        "description": "RELATIVE order of magnitude in HUMAN TIME: xs = under an hour · s = a few hours · m = half a day to a day · l = a few days · xl = to SPLIT. It is estimated ahead of the pick-up of the work; it is an estimate, not a promise. No value = not estimated.",
      +        "enum": [
      +          "xs",
      +          "s",
      +          "m",
      +          "l",
      +          "xl"
      +        ],
      +        "type": "string"
      +      },
      +      "dependsOn": {
      +        "description": "Ids of OTHER tasks of this project that BLOCK this one (distinct from `parentTaskId`, which ORGANIZES without ever blocking). Each id must exist in this project — including in this SAME batch, if the referenced task appears earlier in the array. Omitted = no dependency. Distinct from `status: 'blocked'` (a manual action, independent): blocking BY DEPENDENCY is read via `list_tasks({fields:['dependsOn','openDependencyCount']})` or the `executable` filter.",
      +        "items": {
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 50,
      +        "type": "array"
      +      },
      +      "dueOn": {
      +        "description": "DATED due date (YYYY-MM-DD). Only a date makes \"overdue\" appear.",
      +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +        "type": "string"
      +      },
      +      "dueText": {
      +        "description": "Due date as free text (\"end of the week\"). Kept as is and displayed, but it triggers NO overdue calculation: `dueOn` carries the date when it is known.",
      +        "maxLength": 200,
      +        "type": "string"
      +      },
      +      "executor": {
      +        "description": "WHO is expected to DO the task: `agent` (an AI agent may take it) or `human` (a person must do it — an agent does not claim it and `list_tasks({executable:true})` leaves it out). This is an instruction, not an identity: it does not say who is ASSIGNED. Omitted = unspecified (the default for every existing task).",
      +        "enum": [
      +          "agent",
      +          "human"
      +        ],
      +        "type": "string"
      +      },
      +      "externalId": {
      +        "description": "The identifier of this task IN the originating system (e.g. \"ENG-1234\"). Goes in pair with `externalSource`, in every case.",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "externalSource": {
      +        "description": "The system this task comes from (e.g. \"linear\", \"jira\", \"notion\"). Displayed provenance — does not replace `id` as the idempotence key. Goes in pair with `externalId`, in every case.",
      +        "maxLength": 60,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Identifier supplied by the caller — a key on the external system's side (ticket, import line, an agent's replay key). Omitted = generated by OrgGen (tk_...). If this project already holds a task with this identifier, NOTHING is written for it: it is returned as is (alreadyExisted: true) — a replayed call does not duplicate, and different content on the second call does not overwrite the first. Migration from an external system: the usual pattern is `\"<source>-<external-id>\"` (e.g. `\"linear-ENG-1234\"`) — THIS field carries the idempotence, `externalSource`/`externalId` below only display the provenance.",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "labels": {
      +        "items": {
      +          "maxLength": 60,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 20,
      +        "type": "array"
      +      },
      +      "links": {
      +        "description": "The DELIVERABLES of this task (at most 20) — commit, pull request, deployment, run, document. They are then ADDED one by one through `update_task.addLinks`, not by replacing the list.",
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "documentId": {
      +              "description": "For the `document` type ONLY: the identifier of a document of the project that YOU can read (`list_documents`).",
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "key": {
      +              "description": "Your STABLE key for this deliverable (e.g. `pr-482`): replaying an addition with the same key does not duplicate it, it UPDATES it (this is how you move a PR from `open` to `merged`: a `key` and a `state` are then enough, without repeating the URL). Without a key, the URL (normalized), then `(type, ref)`, designate the entry.",
      +              "maxLength": 255,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "description": "Short displayed label.",
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "ref": {
      +              "description": "Short reference displayed in monospace (sha, PR number, run identifier).",
      +              "maxLength": 80,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "state": {
      +              "description": "The state YOU DECLARE, true at the time of the call — OrgGen never verifies it, the human sees \"declared by the agent\".",
      +              "enum": [
      +                "open",
      +                "merged",
      +                "closed",
      +                "succeeded",
      +                "failed",
      +                "superseded"
      +              ],
      +              "type": "string"
      +            },
      +            "type": {
      +              "description": "The kind of deliverable — closed enumeration.",
      +              "enum": [
      +                "commit",
      +                "pull_request",
      +                "deployment",
      +                "run",
      +                "document",
      +                "other"
      +              ],
      +              "type": "string"
      +            },
      +            "url": {
      +              "description": "ABSOLUTE http(s) address, without embedded username or password. OrgGen never opens it: it is only displayed.",
      +              "maxLength": 2048,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "type"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 20,
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "parentTaskId": {
      +        "description": "Links this task to its parent grouping (\"Part of\") — another task of this project WITHOUT `parentTaskId`, a user story (US) — of which it becomes a SUBTASK. The epic, on the other hand, is the BLOCK (`cellId`): the parent task is never the epic. Omitted = a top-level task (a US). Depth is limited to TWO levels: the target cannot already be a subtask itself. In a BATCH, the target can be created in the SAME call if it appears earlier in the array (with an explicit `id`).",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "priority": {
      +        "enum": [
      +          "urgent",
      +          "high",
      +          "normal",
      +          "low"
      +        ],
      +        "type": "string"
      +      },
      +      "status": {
      +        "enum": [
      +          "todo",
      +          "doing",
      +          "done",
      +          "blocked"
      +        ],
      +        "type": "string"
      +      },
      +      "title": {
      +        "description": "The task label, on one line.",
      +        "maxLength": 500,
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "title"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "items": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "arbitrage": {
      +          "description": "Turns this task into an ARBITRATION (a question with options posed to a human) — see `update_task.arbitrageAction` for the rest of the cycle (approval/challenge by the human, pick-up and closure by the agent). `cellId` omitted: the arbitration takes the block of its parent task (`parentTaskId`), otherwise it is born WITHOUT A SUBJECT (visible in the Arbitrations tab, on no card) — the response says so.",
      +          "properties": {
      +            "options": {
      +              "description": "The PRE-DEFINED answers — at least two, otherwise there is nothing to choose.",
      +              "items": {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "id": {
      +                    "description": "SHORT identifier of the option — cited by `choose`, and not displayed on its own.",
      +                    "maxLength": 100,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "label": {
      +                    "description": "The text of the proposed answer.",
      +                    "maxLength": 300,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "recommended": {
      +                    "anyOf": [
      +                      {
      +                        "additionalProperties": false,
      +                        "properties": {
      +                          "justification": {
      +                            "description": "Why this option is recommended — displayed next to it.",
      +                            "maxLength": 1000,
      +                            "minLength": 1,
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "justification"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Marks THIS option as the agent's recommendation. Omitted/`null` = no recommendation on this option (the normal case)."
      +                  }
      +                },
      +                "required": [
      +                  "id",
      +                  "label"
      +                ],
      +                "type": "object"
      +              },
      +              "maxItems": 8,
      +              "minItems": 2,
      +              "type": "array"
      +            },
      +            "question": {
      +              "description": "The question posed to the human.",
      +              "maxLength": 2000,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "selectionMode": {
      +              "description": "The human selection mode — `single` (one option only, the default) or `multiple` (checkboxes, several options possible). Set once and fixed afterwards.",
      +              "enum": [
      +                "single",
      +                "multiple"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "question",
      +            "options"
      +          ],
      +          "type": "object"
      +        },
      +        "assignees": {
      +          "description": "Assignees. An identifier or a name of a person of the project is RESOLVED; any other string is kept as is as an unresolved designation, not discarded.",
      +          "items": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 10,
      +          "type": "array"
      +        },
      +        "body": {
      +          "description": "Detailed note, optional.",
      +          "maxLength": 20000,
      +          "type": "string"
      +        },
      +        "cellId": {
      +          "description": "The block (cell) the task belongs to — RECOMMENDED in almost every case: a task without a cellId appears on NO card of the canvas, only in the Tasks view. A genuinely cross-cutting task with no single subject (e.g. \"prepare the monthly meeting\") goes without it. Omitted = a task with \"No subject\".",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "complexity": {
      +          "description": "RELATIVE order of magnitude in HUMAN TIME: xs = under an hour · s = a few hours · m = half a day to a day · l = a few days · xl = to SPLIT. It is estimated ahead of the pick-up of the work; it is an estimate, not a promise. No value = not estimated.",
      +          "enum": [
      +            "xs",
      +            "s",
      +            "m",
      +            "l",
      +            "xl"
      +          ],
      +          "type": "string"
      +        },
      +        "dependsOn": {
      +          "description": "Ids of OTHER tasks of this project that BLOCK this one (distinct from `parentTaskId`, which ORGANIZES without ever blocking). Each id must exist in this project — including in this SAME batch, if the referenced task appears earlier in the array. Omitted = no dependency. Distinct from `status: 'blocked'` (a manual action, independent): blocking BY DEPENDENCY is read via `list_tasks({fields:['dependsOn','openDependencyCount']})` or the `executable` filter.",
      +          "items": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 50,
      +          "type": "array"
      +        },
      +        "dueOn": {
      +          "description": "DATED due date (YYYY-MM-DD). Only a date makes \"overdue\" appear.",
      +          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +          "type": "string"
      +        },
      +        "dueText": {
      +          "description": "Due date as free text (\"end of the week\"). Kept as is and displayed, but it triggers NO overdue calculation: `dueOn` carries the date when it is known.",
      +          "maxLength": 200,
      +          "type": "string"
      +        },
      +        "executor": {
      +          "description": "WHO is expected to DO the task: `agent` (an AI agent may take it) or `human` (a person must do it — an agent does not claim it and `list_tasks({executable:true})` leaves it out). This is an instruction, not an identity: it does not say who is ASSIGNED. Omitted = unspecified (the default for every existing task).",
      +          "enum": [
      +            "agent",
      +            "human"
      +          ],
      +          "type": "string"
      +        },
      +        "externalId": {
      +          "description": "The identifier of this task IN the originating system (e.g. \"ENG-1234\"). Goes in pair with `externalSource`, in every case.",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "externalSource": {
      +          "description": "The system this task comes from (e.g. \"linear\", \"jira\", \"notion\"). Displayed provenance — does not replace `id` as the idempotence key. Goes in pair with `externalId`, in every case.",
      +          "maxLength": 60,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "id": {
      +          "description": "Identifier supplied by the caller — a key on the external system's side (ticket, import line, an agent's replay key). Omitted = generated by OrgGen (tk_...). If this project already holds a task with this identifier, NOTHING is written for it: it is returned as is (alreadyExisted: true) — a replayed call does not duplicate, and different content on the second call does not overwrite the first. Migration from an external system: the usual pattern is `\"<source>-<external-id>\"` (e.g. `\"linear-ENG-1234\"`) — THIS field carries the idempotence, `externalSource`/`externalId` below only display the provenance.",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "labels": {
      +          "items": {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 20,
      +          "type": "array"
      +        },
      +        "links": {
      +          "description": "The DELIVERABLES of this task (at most 20) — commit, pull request, deployment, run, document. They are then ADDED one by one through `update_task.addLinks`, not by replacing the list.",
      +          "items": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "documentId": {
      +                "description": "For the `document` type ONLY: the identifier of a document of the project that YOU can read (`list_documents`).",
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "key": {
      +                "description": "Your STABLE key for this deliverable (e.g. `pr-482`): replaying an addition with the same key does not duplicate it, it UPDATES it (this is how you move a PR from `open` to `merged`: a `key` and a `state` are then enough, without repeating the URL). Without a key, the URL (normalized), then `(type, ref)`, designate the entry.",
      +                "maxLength": 255,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "description": "Short displayed label.",
      +                "maxLength": 120,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "ref": {
      +                "description": "Short reference displayed in monospace (sha, PR number, run identifier).",
      +                "maxLength": 80,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "state": {
      +                "description": "The state YOU DECLARE, true at the time of the call — OrgGen never verifies it, the human sees \"declared by the agent\".",
      +                "enum": [
      +                  "open",
      +                  "merged",
      +                  "closed",
      +                  "succeeded",
      +                  "failed",
      +                  "superseded"
      +                ],
      +                "type": "string"
      +              },
      +              "type": {
      +                "description": "The kind of deliverable — closed enumeration.",
      +                "enum": [
      +                  "commit",
      +                  "pull_request",
      +                  "deployment",
      +                  "run",
      +                  "document",
      +                  "other"
      +                ],
      +                "type": "string"
      +              },
      +              "url": {
      +                "description": "ABSOLUTE http(s) address, without embedded username or password. OrgGen never opens it: it is only displayed.",
      +                "maxLength": 2048,
      +                "minLength": 1,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          "maxItems": 20,
      +          "minItems": 1,
      +          "type": "array"
      +        },
      +        "parentTaskId": {
      +          "description": "Links this task to its parent grouping (\"Part of\") — another task of this project WITHOUT `parentTaskId`, a user story (US) — of which it becomes a SUBTASK. The epic, on the other hand, is the BLOCK (`cellId`): the parent task is never the epic. Omitted = a top-level task (a US). Depth is limited to TWO levels: the target cannot already be a subtask itself. In a BATCH, the target can be created in the SAME call if it appears earlier in the array (with an explicit `id`).",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "priority": {
      +          "enum": [
      +            "urgent",
      +            "high",
      +            "normal",
      +            "low"
      +          ],
      +          "type": "string"
      +        },
      +        "status": {
      +          "enum": [
      +            "todo",
      +            "doing",
      +            "done",
      +            "blocked"
      +          ],
      +          "type": "string"
      +        },
      +        "title": {
      +          "description": "The task label, on one line.",
      +          "maxLength": 500,
      +          "minLength": 1,
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "title"
      +      ],
      +      "type": "object"
      +    },
      +    "maxItems": 100,
      +    "minItems": 1,
      +    "type": "array"
      +  }
      +]
  2. Changed4 schema fields changed
    • changedInput schema / properties / batchTitle / description
      Previous value: -"Forme LOT (au moins deux tâches) : la phrase que le bandeau de la vue affichera quand l’humain ouvre `batchUrl`. Ne change rien à ce qui est créé. Maximum 120 caractères."New value: +"BATCH form (at least two tasks): the sentence the view banner will display when the human opens `batchUrl`. Changes nothing about what is created. Maximum 120 characters."
    • changedInput schema / properties / expectedProjectId / description
      Previous value: -"UUID du projet visé par CET appel. Cible RÉELLEMENT ce projet au lieu du projet de session. Refusé sans rien modifier si l'accès n'est pas accordé."New value: +"UUID of the project targeted by THIS call. ACTUALLY targets this project instead of the session project. Refused without changing anything if access is not granted."
    • changedInput schema / properties / tasks / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "arbitrage": {
      -        "description": "Transforme cette tâche en ARBITRAGE — voir `update_task.arbitrageAction` pour la suite du cycle (validation/contestation par l’humain, prise en charge et clôture par l’agent). `cellId` omis : l’arbitrage reprend le bloc de sa tâche parente (`parentTaskId`), sinon il naît SANS SUJET (visible dans l’onglet Arbitrages, sur aucune carte) — la réponse le dit.",
      -        "properties": {
      -          "options": {
      -            "description": "Les réponses PRÉ-DÉFINIES — au moins deux, sinon il n’y a rien à choisir.",
      -            "items": {
      -              "additionalProperties": false,
      -              "properties": {
      -                "id": {
      -                  "description": "Identifiant COURT de l’option — cité par `choose`, jamais affiché seul.",
      -                  "maxLength": 100,
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "label": {
      -                  "description": "Le texte de la réponse proposée.",
      -                  "maxLength": 300,
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "recommended": {
      -                  "anyOf": [
      -                    {
      -                      "additionalProperties": false,
      -                      "properties": {
      -                        "justification": {
      -                          "description": "Pourquoi cette option est recommandée — affichée à côté d’elle.",
      -                          "maxLength": 1000,
      -                          "minLength": 1,
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "justification"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "description": "Marque CETTE option comme la recommandation de l’agent. Omis/`null` = aucune recommandation sur cette option (le cas normal)."
      -                }
      -              },
      -              "required": [
      -                "id",
      -                "label"
      -              ],
      -              "type": "object"
      -            },
      -            "maxItems": 8,
      -            "minItems": 2,
      -            "type": "array"
      -          },
      -          "question": {
      -            "description": "La question posée à l’humain.",
      -            "maxLength": 2000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "selectionMode": {
      -            "description": "Le mode de sélection humaine — `single` (une seule option, le défaut) ou `multiple` (cases à cocher, plusieurs options possibles). Posé une fois, jamais changé ensuite.",
      -            "enum": [
      -              "single",
      -              "multiple"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "question",
      -          "options"
      -        ],
      -        "type": "object"
      -      },
      -      "assignees": {
      -        "description": "Responsables. Un identifiant ou un nom de personne du projet est RÉSOLU ; toute autre chaîne est conservée telle quelle comme désignation non résolue — jamais jetée.",
      -        "items": {
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 10,
      -        "type": "array"
      -      },
      -      "body": {
      -        "description": "Note détaillée, facultative.",
      -        "maxLength": 20000,
      -        "type": "string"
      -      },
      -      "cellId": {
      -        "description": "Le bloc (cellule) auquel la tâche se rattache — RECOMMANDÉ dans presque tous les cas : une tâche sans cellId n’apparaît sur AUCUNE carte du canevas, seulement dans la vue Tâches. L’omission est faite pour une tâche réellement transverse, sans sujet unique (ex. « préparer la réunion mensuelle »). Omis = tâche « sans sujet ».",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "complexity": {
      -        "description": "Ordre de grandeur RELATIF en TEMPS HUMAIN : xs = moins d’une heure · s = quelques heures · m = une demi-journée à un jour · l = quelques jours · xl = à DÉCOUPER. Elle s’estime AVANT la prise du travail ; c’est une estimation, jamais une promesse. Sans valeur = non estimée.",
      -        "enum": [
      -          "xs",
      -          "s",
      -          "m",
      -          "l",
      -          "xl"
      -        ],
      -        "type": "string"
      -      },
      -      "dependsOn": {
      -        "description": "Ids d'AUTRES tâches de ce projet qui BLOQUENT celle-ci (distinct de `parentTaskId`, qui ORGANISE sans jamais bloquer). Chaque id doit exister dans ce projet — y compris dans ce MÊME lot, si la tâche référencée apparaît AVANT. Omis = aucune dépendance. Distinct de `status: 'blocked'` (un geste manuel, indépendant) : le blocage PAR DÉPENDANCE se lit via `list_tasks({fields:['dependsOn','openDependencyCount']})` ou le filtre `executable`.",
      -        "items": {
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 50,
      -        "type": "array"
      -      },
      -      "dueOn": {
      -        "description": "Échéance DATÉE (YYYY-MM-DD). Seule une date fait apparaître « en retard ».",
      -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -        "type": "string"
      -      },
      -      "dueText": {
      -        "description": "Échéance en texte libre (« fin de semaine »). Conservée telle quelle et affichée, mais elle ne déclenche AUCUN calcul de retard : `dueOn` porte la date quand elle est connue.",
      -        "maxLength": 200,
      -        "type": "string"
      -      },
      -      "externalId": {
      -        "description": "L'identifiant de cette tâche DANS le système d'origine (ex. \"ENG-1234\"). Toujours accompagné de `externalSource`.",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "externalSource": {
      -        "description": "Le système d'origine de cette tâche (ex. \"linear\", \"jira\", \"notion\"). Provenance affichée — ne remplace pas `id` comme clé d'idempotence. Toujours accompagnée de `externalId`.",
      -        "maxLength": 60,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Identifiant fourni par l'appelant — une clé côté système externe (ticket, ligne d'import, clé de rejeu d'un agent). Omis = généré par OrgGen (tk_...). Si ce projet porte déjà une tâche avec cet identifiant, RIEN n'est écrit pour elle : elle est rendue telle quelle (alreadyExisted: true) — un appel rejoué ne duplique JAMAIS, et un contenu différent sur le second appel n'écrase pas le premier. Migration depuis un système externe : le patron courant est `\"<source>-<id-externe>\"` (ex. `\"linear-ENG-1234\"`) — c'est CE champ qui porte l'idempotence, `externalSource`/`externalId` ci-dessous ne font qu'afficher la provenance.",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "labels": {
      -        "items": {
      -          "maxLength": 60,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 20,
      -        "type": "array"
      -      },
      -      "links": {
      -        "description": "Les LIVRABLES de cette tâche (au plus 20) — commit, pull request, déploiement, run, document. Ils s’AJOUTENT ensuite un à un par `update_task.addLinks`, jamais en remplaçant la liste.",
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "documentId": {
      -              "description": "Pour le type `document` SEUL : l’identifiant d’un document du projet que TU peux lire (`list_documents`).",
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "key": {
      -              "description": "Ta clé STABLE pour ce livrable (ex. `pr-482`) : rejouer un ajout avec la même clé ne le duplique pas, il le MET À JOUR (c’est ainsi que tu passes une PR de `open` à `merged` : une `key` et un `state` suffisent alors, sans répéter l’URL). Sans clé, l’URL (normalisée), puis `(type, ref)`, désignent l’entrée.",
      -              "maxLength": 255,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "description": "Libellé court affiché.",
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "ref": {
      -              "description": "Référence courte affichée en monospace (sha, numéro de PR, identifiant de run).",
      -              "maxLength": 80,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "state": {
      -              "description": "L’état que TU DÉCLARES, vrai au moment de l’appel — OrgGen ne le vérifie jamais, l’humain voit « déclaré par l’agent ».",
      -              "enum": [
      -                "open",
      -                "merged",
      -                "closed",
      -                "succeeded",
      -                "failed",
      -                "superseded"
      -              ],
      -              "type": "string"
      -            },
      -            "type": {
      -              "description": "Le genre de livrable — énumération fermée.",
      -              "enum": [
      -                "commit",
      -                "pull_request",
      -                "deployment",
      -                "run",
      -                "document",
      -                "other"
      -              ],
      -              "type": "string"
      -            },
      -            "url": {
      -              "description": "Adresse http(s) ABSOLUE, sans identifiant ni mot de passe intégrés. OrgGen ne l’ouvre jamais : elle n’est qu’affichée.",
      -              "maxLength": 2048,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "type"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 20,
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "parentTaskId": {
      -        "description": "Rattache cette tâche à son regroupement parent (« Fait partie de ») — une autre tâche de ce projet SANS `parentTaskId`, une US — dont elle devient une SOUS-TÂCHE. L’Épique, elle, est le BLOC (`cellId`) : la tâche parente n’est jamais l’Épique. Omis = tâche de premier niveau (une US). Profondeur limitée à DEUX niveaux : la cible ne peut pas être déjà elle-même une sous-tâche. Dans un LOT, la cible peut être créée dans le MÊME appel si elle apparaît AVANT (avec un `id` explicite).",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "priority": {
      -        "enum": [
      -          "urgent",
      -          "high",
      -          "normal",
      -          "low"
      -        ],
      -        "type": "string"
      -      },
      -      "status": {
      -        "enum": [
      -          "todo",
      -          "doing",
      -          "done",
      -          "blocked"
      -        ],
      -        "type": "string"
      -      },
      -      "title": {
      -        "description": "Le libellé de la tâche, en une ligne.",
      -        "maxLength": 500,
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "title"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "items": {
      -      "additionalProperties": false,
      -      "properties": {
      -        "arbitrage": {
      -          "description": "Transforme cette tâche en ARBITRAGE — voir `update_task.arbitrageAction` pour la suite du cycle (validation/contestation par l’humain, prise en charge et clôture par l’agent). `cellId` omis : l’arbitrage reprend le bloc de sa tâche parente (`parentTaskId`), sinon il naît SANS SUJET (visible dans l’onglet Arbitrages, sur aucune carte) — la réponse le dit.",
      -          "properties": {
      -            "options": {
      -              "description": "Les réponses PRÉ-DÉFINIES — au moins deux, sinon il n’y a rien à choisir.",
      -              "items": {
      -                "additionalProperties": false,
      -                "properties": {
      -                  "id": {
      -                    "description": "Identifiant COURT de l’option — cité par `choose`, jamais affiché seul.",
      -                    "maxLength": 100,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "label": {
      -                    "description": "Le texte de la réponse proposée.",
      -                    "maxLength": 300,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "recommended": {
      -                    "anyOf": [
      -                      {
      -                        "additionalProperties": false,
      -                        "properties": {
      -                          "justification": {
      -                            "description": "Pourquoi cette option est recommandée — affichée à côté d’elle.",
      -                            "maxLength": 1000,
      -                            "minLength": 1,
      -                            "type": "string"
      -                          }
      -                        },
      -                        "required": [
      -                          "justification"
      -                        ],
      -                        "type": "object"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "Marque CETTE option comme la recommandation de l’agent. Omis/`null` = aucune recommandation sur cette option (le cas normal)."
      -                  }
      -                },
      -                "required": [
      -                  "id",
      -                  "label"
      -                ],
      -                "type": "object"
      -              },
      -              "maxItems": 8,
      -              "minItems": 2,
      -              "type": "array"
      -            },
      -            "question": {
      -              "description": "La question posée à l’humain.",
      -              "maxLength": 2000,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "selectionMode": {
      -              "description": "Le mode de sélection humaine — `single` (une seule option, le défaut) ou `multiple` (cases à cocher, plusieurs options possibles). Posé une fois, jamais changé ensuite.",
      -              "enum": [
      -                "single",
      -                "multiple"
      -              ],
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "question",
      -            "options"
      -          ],
      -          "type": "object"
      -        },
      -        "assignees": {
      -          "description": "Responsables. Un identifiant ou un nom de personne du projet est RÉSOLU ; toute autre chaîne est conservée telle quelle comme désignation non résolue — jamais jetée.",
      -          "items": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 10,
      -          "type": "array"
      -        },
      -        "body": {
      -          "description": "Note détaillée, facultative.",
      -          "maxLength": 20000,
      -          "type": "string"
      -        },
      -        "cellId": {
      -          "description": "Le bloc (cellule) auquel la tâche se rattache — RECOMMANDÉ dans presque tous les cas : une tâche sans cellId n’apparaît sur AUCUNE carte du canevas, seulement dans la vue Tâches. L’omission est faite pour une tâche réellement transverse, sans sujet unique (ex. « préparer la réunion mensuelle »). Omis = tâche « sans sujet ».",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "complexity": {
      -          "description": "Ordre de grandeur RELATIF en TEMPS HUMAIN : xs = moins d’une heure · s = quelques heures · m = une demi-journée à un jour · l = quelques jours · xl = à DÉCOUPER. Elle s’estime AVANT la prise du travail ; c’est une estimation, jamais une promesse. Sans valeur = non estimée.",
      -          "enum": [
      -            "xs",
      -            "s",
      -            "m",
      -            "l",
      -            "xl"
      -          ],
      -          "type": "string"
      -        },
      -        "dependsOn": {
      -          "description": "Ids d'AUTRES tâches de ce projet qui BLOQUENT celle-ci (distinct de `parentTaskId`, qui ORGANISE sans jamais bloquer). Chaque id doit exister dans ce projet — y compris dans ce MÊME lot, si la tâche référencée apparaît AVANT. Omis = aucune dépendance. Distinct de `status: 'blocked'` (un geste manuel, indépendant) : le blocage PAR DÉPENDANCE se lit via `list_tasks({fields:['dependsOn','openDependencyCount']})` ou le filtre `executable`.",
      -          "items": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 50,
      -          "type": "array"
      -        },
      -        "dueOn": {
      -          "description": "Échéance DATÉE (YYYY-MM-DD). Seule une date fait apparaître « en retard ».",
      -          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -          "type": "string"
      -        },
      -        "dueText": {
      -          "description": "Échéance en texte libre (« fin de semaine »). Conservée telle quelle et affichée, mais elle ne déclenche AUCUN calcul de retard : `dueOn` porte la date quand elle est connue.",
      -          "maxLength": 200,
      -          "type": "string"
      -        },
      -        "externalId": {
      -          "description": "L'identifiant de cette tâche DANS le système d'origine (ex. \"ENG-1234\"). Toujours accompagné de `externalSource`.",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "externalSource": {
      -          "description": "Le système d'origine de cette tâche (ex. \"linear\", \"jira\", \"notion\"). Provenance affichée — ne remplace pas `id` comme clé d'idempotence. Toujours accompagnée de `externalId`.",
      -          "maxLength": 60,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "id": {
      -          "description": "Identifiant fourni par l'appelant — une clé côté système externe (ticket, ligne d'import, clé de rejeu d'un agent). Omis = généré par OrgGen (tk_...). Si ce projet porte déjà une tâche avec cet identifiant, RIEN n'est écrit pour elle : elle est rendue telle quelle (alreadyExisted: true) — un appel rejoué ne duplique JAMAIS, et un contenu différent sur le second appel n'écrase pas le premier. Migration depuis un système externe : le patron courant est `\"<source>-<id-externe>\"` (ex. `\"linear-ENG-1234\"`) — c'est CE champ qui porte l'idempotence, `externalSource`/`externalId` ci-dessous ne font qu'afficher la provenance.",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "labels": {
      -          "items": {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 20,
      -          "type": "array"
      -        },
      -        "links": {
      -          "description": "Les LIVRABLES de cette tâche (au plus 20) — commit, pull request, déploiement, run, document. Ils s’AJOUTENT ensuite un à un par `update_task.addLinks`, jamais en remplaçant la liste.",
      -          "items": {
      -            "additionalProperties": false,
      -            "properties": {
      -              "documentId": {
      -                "description": "Pour le type `document` SEUL : l’identifiant d’un document du projet que TU peux lire (`list_documents`).",
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "key": {
      -                "description": "Ta clé STABLE pour ce livrable (ex. `pr-482`) : rejouer un ajout avec la même clé ne le duplique pas, il le MET À JOUR (c’est ainsi que tu passes une PR de `open` à `merged` : une `key` et un `state` suffisent alors, sans répéter l’URL). Sans clé, l’URL (normalisée), puis `(type, ref)`, désignent l’entrée.",
      -                "maxLength": 255,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "description": "Libellé court affiché.",
      -                "maxLength": 120,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "ref": {
      -                "description": "Référence courte affichée en monospace (sha, numéro de PR, identifiant de run).",
      -                "maxLength": 80,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "state": {
      -                "description": "L’état que TU DÉCLARES, vrai au moment de l’appel — OrgGen ne le vérifie jamais, l’humain voit « déclaré par l’agent ».",
      -                "enum": [
      -                  "open",
      -                  "merged",
      -                  "closed",
      -                  "succeeded",
      -                  "failed",
      -                  "superseded"
      -                ],
      -                "type": "string"
      -              },
      -              "type": {
      -                "description": "Le genre de livrable — énumération fermée.",
      -                "enum": [
      -                  "commit",
      -                  "pull_request",
      -                  "deployment",
      -                  "run",
      -                  "document",
      -                  "other"
      -                ],
      -                "type": "string"
      -              },
      -              "url": {
      -                "description": "Adresse http(s) ABSOLUE, sans identifiant ni mot de passe intégrés. OrgGen ne l’ouvre jamais : elle n’est qu’affichée.",
      -                "maxLength": 2048,
      -                "minLength": 1,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          "maxItems": 20,
      -          "minItems": 1,
      -          "type": "array"
      -        },
      -        "parentTaskId": {
      -          "description": "Rattache cette tâche à son regroupement parent (« Fait partie de ») — une autre tâche de ce projet SANS `parentTaskId`, une US — dont elle devient une SOUS-TÂCHE. L’Épique, elle, est le BLOC (`cellId`) : la tâche parente n’est jamais l’Épique. Omis = tâche de premier niveau (une US). Profondeur limitée à DEUX niveaux : la cible ne peut pas être déjà elle-même une sous-tâche. Dans un LOT, la cible peut être créée dans le MÊME appel si elle apparaît AVANT (avec un `id` explicite).",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "priority": {
      -          "enum": [
      -            "urgent",
      -            "high",
      -            "normal",
      -            "low"
      -          ],
      -          "type": "string"
      -        },
      -        "status": {
      -          "enum": [
      -            "todo",
      -            "doing",
      -            "done",
      -            "blocked"
      -          ],
      -          "type": "string"
      -        },
      -        "title": {
      -          "description": "Le libellé de la tâche, en une ligne.",
      -          "maxLength": 500,
      -          "minLength": 1,
      -          "type": "string"
      -        }
      -      },
      -      "required": [
      -        "title"
      -      ],
      -      "type": "object"
      -    },
      -    "maxItems": 100,
      -    "minItems": 1,
      -    "type": "array"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "arbitrage": {
      +        "description": "Turns this task into an ARBITRATION (a question with options posed to a human) — see `update_task.arbitrageAction` for the rest of the cycle (approval/challenge by the human, pick-up and closure by the agent). `cellId` omitted: the arbitration takes the block of its parent task (`parentTaskId`), otherwise it is born WITHOUT A SUBJECT (visible in the Arbitrations tab, on no card) — the response says so.",
      +        "properties": {
      +          "options": {
      +            "description": "The PRE-DEFINED answers — at least two, otherwise there is nothing to choose.",
      +            "items": {
      +              "additionalProperties": false,
      +              "properties": {
      +                "id": {
      +                  "description": "SHORT identifier of the option — cited by `choose`, and not displayed on its own.",
      +                  "maxLength": 100,
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "label": {
      +                  "description": "The text of the proposed answer.",
      +                  "maxLength": 300,
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "recommended": {
      +                  "anyOf": [
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "justification": {
      +                          "description": "Why this option is recommended — displayed next to it.",
      +                          "maxLength": 1000,
      +                          "minLength": 1,
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "justification"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "Marks THIS option as the agent's recommendation. Omitted/`null` = no recommendation on this option (the normal case)."
      +                }
      +              },
      +              "required": [
      +                "id",
      +                "label"
      +              ],
      +              "type": "object"
      +            },
      +            "maxItems": 8,
      +            "minItems": 2,
      +            "type": "array"
      +          },
      +          "question": {
      +            "description": "The question posed to the human.",
      +            "maxLength": 2000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "selectionMode": {
      +            "description": "The human selection mode — `single` (one option only, the default) or `multiple` (checkboxes, several options possible). Set once and fixed afterwards.",
      +            "enum": [
      +              "single",
      +              "multiple"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "question",
      +          "options"
      +        ],
      +        "type": "object"
      +      },
      +      "assignees": {
      +        "description": "Assignees. An identifier or a name of a person of the project is RESOLVED; any other string is kept as is as an unresolved designation, not discarded.",
      +        "items": {
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 10,
      +        "type": "array"
      +      },
      +      "body": {
      +        "description": "Detailed note, optional.",
      +        "maxLength": 20000,
      +        "type": "string"
      +      },
      +      "cellId": {
      +        "description": "The block (cell) the task belongs to — RECOMMENDED in almost every case: a task without a cellId appears on NO card of the canvas, only in the Tasks view. A genuinely cross-cutting task with no single subject (e.g. \"prepare the monthly meeting\") goes without it. Omitted = a task with \"No subject\".",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "complexity": {
      +        "description": "RELATIVE order of magnitude in HUMAN TIME: xs = under an hour · s = a few hours · m = half a day to a day · l = a few days · xl = to SPLIT. It is estimated ahead of the pick-up of the work; it is an estimate, not a promise. No value = not estimated.",
      +        "enum": [
      +          "xs",
      +          "s",
      +          "m",
      +          "l",
      +          "xl"
      +        ],
      +        "type": "string"
      +      },
      +      "dependsOn": {
      +        "description": "Ids of OTHER tasks of this project that BLOCK this one (distinct from `parentTaskId`, which ORGANIZES without ever blocking). Each id must exist in this project — including in this SAME batch, if the referenced task appears earlier in the array. Omitted = no dependency. Distinct from `status: 'blocked'` (a manual action, independent): blocking BY DEPENDENCY is read via `list_tasks({fields:['dependsOn','openDependencyCount']})` or the `executable` filter.",
      +        "items": {
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 50,
      +        "type": "array"
      +      },
      +      "dueOn": {
      +        "description": "DATED due date (YYYY-MM-DD). Only a date makes \"overdue\" appear.",
      +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +        "type": "string"
      +      },
      +      "dueText": {
      +        "description": "Due date as free text (\"end of the week\"). Kept as is and displayed, but it triggers NO overdue calculation: `dueOn` carries the date when it is known.",
      +        "maxLength": 200,
      +        "type": "string"
      +      },
      +      "externalId": {
      +        "description": "The identifier of this task IN the originating system (e.g. \"ENG-1234\"). Goes in pair with `externalSource`, in every case.",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "externalSource": {
      +        "description": "The system this task comes from (e.g. \"linear\", \"jira\", \"notion\"). Displayed provenance — does not replace `id` as the idempotence key. Goes in pair with `externalId`, in every case.",
      +        "maxLength": 60,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Identifier supplied by the caller — a key on the external system's side (ticket, import line, an agent's replay key). Omitted = generated by OrgGen (tk_...). If this project already holds a task with this identifier, NOTHING is written for it: it is returned as is (alreadyExisted: true) — a replayed call does not duplicate, and different content on the second call does not overwrite the first. Migration from an external system: the usual pattern is `\"<source>-<external-id>\"` (e.g. `\"linear-ENG-1234\"`) — THIS field carries the idempotence, `externalSource`/`externalId` below only display the provenance.",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "labels": {
      +        "items": {
      +          "maxLength": 60,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 20,
      +        "type": "array"
      +      },
      +      "links": {
      +        "description": "The DELIVERABLES of this task (at most 20) — commit, pull request, deployment, run, document. They are then ADDED one by one through `update_task.addLinks`, not by replacing the list.",
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "documentId": {
      +              "description": "For the `document` type ONLY: the identifier of a document of the project that YOU can read (`list_documents`).",
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "key": {
      +              "description": "Your STABLE key for this deliverable (e.g. `pr-482`): replaying an addition with the same key does not duplicate it, it UPDATES it (this is how you move a PR from `open` to `merged`: a `key` and a `state` are then enough, without repeating the URL). Without a key, the URL (normalized), then `(type, ref)`, designate the entry.",
      +              "maxLength": 255,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "description": "Short displayed label.",
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "ref": {
      +              "description": "Short reference displayed in monospace (sha, PR number, run identifier).",
      +              "maxLength": 80,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "state": {
      +              "description": "The state YOU DECLARE, true at the time of the call — OrgGen never verifies it, the human sees \"declared by the agent\".",
      +              "enum": [
      +                "open",
      +                "merged",
      +                "closed",
      +                "succeeded",
      +                "failed",
      +                "superseded"
      +              ],
      +              "type": "string"
      +            },
      +            "type": {
      +              "description": "The kind of deliverable — closed enumeration.",
      +              "enum": [
      +                "commit",
      +                "pull_request",
      +                "deployment",
      +                "run",
      +                "document",
      +                "other"
      +              ],
      +              "type": "string"
      +            },
      +            "url": {
      +              "description": "ABSOLUTE http(s) address, without embedded username or password. OrgGen never opens it: it is only displayed.",
      +              "maxLength": 2048,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "type"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 20,
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "parentTaskId": {
      +        "description": "Links this task to its parent grouping (\"Part of\") — another task of this project WITHOUT `parentTaskId`, a user story (US) — of which it becomes a SUBTASK. The epic, on the other hand, is the BLOCK (`cellId`): the parent task is never the epic. Omitted = a top-level task (a US). Depth is limited to TWO levels: the target cannot already be a subtask itself. In a BATCH, the target can be created in the SAME call if it appears earlier in the array (with an explicit `id`).",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "priority": {
      +        "enum": [
      +          "urgent",
      +          "high",
      +          "normal",
      +          "low"
      +        ],
      +        "type": "string"
      +      },
      +      "status": {
      +        "enum": [
      +          "todo",
      +          "doing",
      +          "done",
      +          "blocked"
      +        ],
      +        "type": "string"
      +      },
      +      "title": {
      +        "description": "The task label, on one line.",
      +        "maxLength": 500,
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "title"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "items": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "arbitrage": {
      +          "description": "Turns this task into an ARBITRATION (a question with options posed to a human) — see `update_task.arbitrageAction` for the rest of the cycle (approval/challenge by the human, pick-up and closure by the agent). `cellId` omitted: the arbitration takes the block of its parent task (`parentTaskId`), otherwise it is born WITHOUT A SUBJECT (visible in the Arbitrations tab, on no card) — the response says so.",
      +          "properties": {
      +            "options": {
      +              "description": "The PRE-DEFINED answers — at least two, otherwise there is nothing to choose.",
      +              "items": {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "id": {
      +                    "description": "SHORT identifier of the option — cited by `choose`, and not displayed on its own.",
      +                    "maxLength": 100,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "label": {
      +                    "description": "The text of the proposed answer.",
      +                    "maxLength": 300,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "recommended": {
      +                    "anyOf": [
      +                      {
      +                        "additionalProperties": false,
      +                        "properties": {
      +                          "justification": {
      +                            "description": "Why this option is recommended — displayed next to it.",
      +                            "maxLength": 1000,
      +                            "minLength": 1,
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "justification"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Marks THIS option as the agent's recommendation. Omitted/`null` = no recommendation on this option (the normal case)."
      +                  }
      +                },
      +                "required": [
      +                  "id",
      +                  "label"
      +                ],
      +                "type": "object"
      +              },
      +              "maxItems": 8,
      +              "minItems": 2,
      +              "type": "array"
      +            },
      +            "question": {
      +              "description": "The question posed to the human.",
      +              "maxLength": 2000,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "selectionMode": {
      +              "description": "The human selection mode — `single` (one option only, the default) or `multiple` (checkboxes, several options possible). Set once and fixed afterwards.",
      +              "enum": [
      +                "single",
      +                "multiple"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "question",
      +            "options"
      +          ],
      +          "type": "object"
      +        },
      +        "assignees": {
      +          "description": "Assignees. An identifier or a name of a person of the project is RESOLVED; any other string is kept as is as an unresolved designation, not discarded.",
      +          "items": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 10,
      +          "type": "array"
      +        },
      +        "body": {
      +          "description": "Detailed note, optional.",
      +          "maxLength": 20000,
      +          "type": "string"
      +        },
      +        "cellId": {
      +          "description": "The block (cell) the task belongs to — RECOMMENDED in almost every case: a task without a cellId appears on NO card of the canvas, only in the Tasks view. A genuinely cross-cutting task with no single subject (e.g. \"prepare the monthly meeting\") goes without it. Omitted = a task with \"No subject\".",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "complexity": {
      +          "description": "RELATIVE order of magnitude in HUMAN TIME: xs = under an hour · s = a few hours · m = half a day to a day · l = a few days · xl = to SPLIT. It is estimated ahead of the pick-up of the work; it is an estimate, not a promise. No value = not estimated.",
      +          "enum": [
      +            "xs",
      +            "s",
      +            "m",
      +            "l",
      +            "xl"
      +          ],
      +          "type": "string"
      +        },
      +        "dependsOn": {
      +          "description": "Ids of OTHER tasks of this project that BLOCK this one (distinct from `parentTaskId`, which ORGANIZES without ever blocking). Each id must exist in this project — including in this SAME batch, if the referenced task appears earlier in the array. Omitted = no dependency. Distinct from `status: 'blocked'` (a manual action, independent): blocking BY DEPENDENCY is read via `list_tasks({fields:['dependsOn','openDependencyCount']})` or the `executable` filter.",
      +          "items": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 50,
      +          "type": "array"
      +        },
      +        "dueOn": {
      +          "description": "DATED due date (YYYY-MM-DD). Only a date makes \"overdue\" appear.",
      +          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +          "type": "string"
      +        },
      +        "dueText": {
      +          "description": "Due date as free text (\"end of the week\"). Kept as is and displayed, but it triggers NO overdue calculation: `dueOn` carries the date when it is known.",
      +          "maxLength": 200,
      +          "type": "string"
      +        },
      +        "externalId": {
      +          "description": "The identifier of this task IN the originating system (e.g. \"ENG-1234\"). Goes in pair with `externalSource`, in every case.",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "externalSource": {
      +          "description": "The system this task comes from (e.g. \"linear\", \"jira\", \"notion\"). Displayed provenance — does not replace `id` as the idempotence key. Goes in pair with `externalId`, in every case.",
      +          "maxLength": 60,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "id": {
      +          "description": "Identifier supplied by the caller — a key on the external system's side (ticket, import line, an agent's replay key). Omitted = generated by OrgGen (tk_...). If this project already holds a task with this identifier, NOTHING is written for it: it is returned as is (alreadyExisted: true) — a replayed call does not duplicate, and different content on the second call does not overwrite the first. Migration from an external system: the usual pattern is `\"<source>-<external-id>\"` (e.g. `\"linear-ENG-1234\"`) — THIS field carries the idempotence, `externalSource`/`externalId` below only display the provenance.",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "labels": {
      +          "items": {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 20,
      +          "type": "array"
      +        },
      +        "links": {
      +          "description": "The DELIVERABLES of this task (at most 20) — commit, pull request, deployment, run, document. They are then ADDED one by one through `update_task.addLinks`, not by replacing the list.",
      +          "items": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "documentId": {
      +                "description": "For the `document` type ONLY: the identifier of a document of the project that YOU can read (`list_documents`).",
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "key": {
      +                "description": "Your STABLE key for this deliverable (e.g. `pr-482`): replaying an addition with the same key does not duplicate it, it UPDATES it (this is how you move a PR from `open` to `merged`: a `key` and a `state` are then enough, without repeating the URL). Without a key, the URL (normalized), then `(type, ref)`, designate the entry.",
      +                "maxLength": 255,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "description": "Short displayed label.",
      +                "maxLength": 120,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "ref": {
      +                "description": "Short reference displayed in monospace (sha, PR number, run identifier).",
      +                "maxLength": 80,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "state": {
      +                "description": "The state YOU DECLARE, true at the time of the call — OrgGen never verifies it, the human sees \"declared by the agent\".",
      +                "enum": [
      +                  "open",
      +                  "merged",
      +                  "closed",
      +                  "succeeded",
      +                  "failed",
      +                  "superseded"
      +                ],
      +                "type": "string"
      +              },
      +              "type": {
      +                "description": "The kind of deliverable — closed enumeration.",
      +                "enum": [
      +                  "commit",
      +                  "pull_request",
      +                  "deployment",
      +                  "run",
      +                  "document",
      +                  "other"
      +                ],
      +                "type": "string"
      +              },
      +              "url": {
      +                "description": "ABSOLUTE http(s) address, without embedded username or password. OrgGen never opens it: it is only displayed.",
      +                "maxLength": 2048,
      +                "minLength": 1,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          "maxItems": 20,
      +          "minItems": 1,
      +          "type": "array"
      +        },
      +        "parentTaskId": {
      +          "description": "Links this task to its parent grouping (\"Part of\") — another task of this project WITHOUT `parentTaskId`, a user story (US) — of which it becomes a SUBTASK. The epic, on the other hand, is the BLOCK (`cellId`): the parent task is never the epic. Omitted = a top-level task (a US). Depth is limited to TWO levels: the target cannot already be a subtask itself. In a BATCH, the target can be created in the SAME call if it appears earlier in the array (with an explicit `id`).",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "priority": {
      +          "enum": [
      +            "urgent",
      +            "high",
      +            "normal",
      +            "low"
      +          ],
      +          "type": "string"
      +        },
      +        "status": {
      +          "enum": [
      +            "todo",
      +            "doing",
      +            "done",
      +            "blocked"
      +          ],
      +          "type": "string"
      +        },
      +        "title": {
      +          "description": "The task label, on one line.",
      +          "maxLength": 500,
      +          "minLength": 1,
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "title"
      +      ],
      +      "type": "object"
      +    },
      +    "maxItems": 100,
      +    "minItems": 1,
      +    "type": "array"
      +  }
      +]
    • changedInput schema / properties / tasks / description
      Previous value: -"UNE tâche (objet) ou JUSQU’À 100 (tableau) — même paramètre dans les deux cas, comme `status` de `list_tasks`. Une seule écriture, un seul verrou."New value: +"ONE task (object) or UP TO 100 (array) — same parameter in both cases, like `status` of `list_tasks`. A single write, a single lock."
  3. Changed1 schema field changed
    • changedInput schema / properties / tasks / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "arbitrage": {
      -        "description": "Transforme cette tâche en ARBITRAGE — voir `update_task.arbitrageAction` pour la suite du cycle (validation/contestation par l’humain, prise en charge et clôture par l’agent). `cellId` omis : l’arbitrage reprend le bloc de sa tâche parente (`parentTaskId`), sinon il naît SANS SUJET (visible dans l’onglet Arbitrages, sur aucune carte) — la réponse le dit.",
      -        "properties": {
      -          "options": {
      -            "description": "Les réponses PRÉ-DÉFINIES — au moins deux, sinon il n’y a rien à choisir.",
      -            "items": {
      -              "additionalProperties": false,
      -              "properties": {
      -                "id": {
      -                  "description": "Identifiant COURT de l’option — cité par `choose`, jamais affiché seul.",
      -                  "maxLength": 100,
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "label": {
      -                  "description": "Le texte de la réponse proposée.",
      -                  "maxLength": 300,
      -                  "minLength": 1,
      -                  "type": "string"
      -                },
      -                "recommended": {
      -                  "anyOf": [
      -                    {
      -                      "additionalProperties": false,
      -                      "properties": {
      -                        "justification": {
      -                          "description": "Pourquoi cette option est recommandée — affichée à côté d’elle.",
      -                          "maxLength": 1000,
      -                          "minLength": 1,
      -                          "type": "string"
      -                        }
      -                      },
      -                      "required": [
      -                        "justification"
      -                      ],
      -                      "type": "object"
      -                    },
      -                    {
      -                      "type": "null"
      -                    }
      -                  ],
      -                  "description": "Marque CETTE option comme la recommandation de l’agent. Omis/`null` = aucune recommandation sur cette option (le cas normal)."
      -                }
      -              },
      -              "required": [
      -                "id",
      -                "label"
      -              ],
      -              "type": "object"
      -            },
      -            "maxItems": 8,
      -            "minItems": 2,
      -            "type": "array"
      -          },
      -          "question": {
      -            "description": "La question posée à l’humain.",
      -            "maxLength": 2000,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "selectionMode": {
      -            "description": "Le mode de sélection humaine — `single` (une seule option, le défaut) ou `multiple` (cases à cocher, plusieurs options possibles). Posé une fois, jamais changé ensuite.",
      -            "enum": [
      -              "single",
      -              "multiple"
      -            ],
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "question",
      -          "options"
      -        ],
      -        "type": "object"
      -      },
      -      "assignees": {
      -        "description": "Responsables. Un identifiant ou un nom de personne du projet est RÉSOLU ; toute autre chaîne est conservée telle quelle comme désignation non résolue — jamais jetée.",
      -        "items": {
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 10,
      -        "type": "array"
      -      },
      -      "body": {
      -        "description": "Note détaillée, facultative.",
      -        "maxLength": 20000,
      -        "type": "string"
      -      },
      -      "cellId": {
      -        "description": "Le bloc (cellule) auquel la tâche se rattache — RECOMMANDÉ dans presque tous les cas : une tâche sans cellId n’apparaît sur AUCUNE carte du canevas, seulement dans la vue Tâches. Ne l’omets JAMAIS par réflexe quand un bloc évident existe déjà pour ce travail — réserve l’omission à une tâche réellement transverse, sans sujet unique (ex. « préparer la réunion mensuelle »). Omis = tâche « sans sujet ».",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "complexity": {
      -        "description": "Ordre de grandeur RELATIF en TEMPS HUMAIN : xs = moins d’une heure · s = quelques heures · m = une demi-journée à un jour · l = quelques jours · xl = à DÉCOUPER. Pose-la AVANT la prise du travail ; c’est une estimation, jamais une promesse. Sans valeur = non estimée.",
      -        "enum": [
      -          "xs",
      -          "s",
      -          "m",
      -          "l",
      -          "xl"
      -        ],
      -        "type": "string"
      -      },
      -      "dependsOn": {
      -        "description": "Ids d'AUTRES tâches de ce projet qui BLOQUENT celle-ci (distinct de `parentTaskId`, qui ORGANISE sans jamais bloquer). Chaque id doit exister dans ce projet — y compris dans ce MÊME lot, si la tâche référencée apparaît AVANT. Omis = aucune dépendance. Ne PAS confondre avec `status: 'blocked'` (un geste manuel, indépendant) : le blocage PAR DÉPENDANCE se lit via `list_tasks({fields:['dependsOn','openDependencyCount']})` ou le filtre `executable`.",
      -        "items": {
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 50,
      -        "type": "array"
      -      },
      -      "dueOn": {
      -        "description": "Échéance DATÉE (YYYY-MM-DD). Seule une date fait apparaître « en retard ».",
      -        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -        "type": "string"
      -      },
      -      "dueText": {
      -        "description": "Échéance en texte libre (« fin de semaine »). Conservée telle quelle et affichée, mais elle ne déclenche AUCUN calcul de retard : préfère `dueOn` quand la date est connue.",
      -        "maxLength": 200,
      -        "type": "string"
      -      },
      -      "externalId": {
      -        "description": "L'identifiant de cette tâche DANS le système d'origine (ex. \"ENG-1234\"). Va TOUJOURS avec `externalSource`.",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "externalSource": {
      -        "description": "Le système d'origine de cette tâche (ex. \"linear\", \"jira\", \"notion\"). Provenance affichée — ne remplace pas `id` comme clé d'idempotence. Va TOUJOURS avec `externalId`.",
      -        "maxLength": 60,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "id": {
      -        "description": "Identifiant fourni par l'appelant — une clé côté système externe (ticket, ligne d'import, clé de rejeu d'un agent). Omis = généré par OrgGen (tk_...). Si ce projet porte déjà une tâche avec cet identifiant, RIEN n'est écrit pour elle : elle est rendue telle quelle (alreadyExisted: true) — un appel rejoué ne duplique JAMAIS, et un contenu différent sur le second appel n'écrase pas le premier. Migration depuis un système externe : préfère le patron `\"<source>-<id-externe>\"` (ex. `\"linear-ENG-1234\"`) — c'est CE champ qui porte l'idempotence, `externalSource`/`externalId` ci-dessous ne font qu'afficher la provenance.",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "labels": {
      -        "items": {
      -          "maxLength": 60,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 20,
      -        "type": "array"
      -      },
      -      "links": {
      -        "description": "Les LIVRABLES de cette tâche (au plus 20) — commit, pull request, déploiement, run, document. Ils s’AJOUTENT ensuite un à un par `update_task.addLinks`, jamais en remplaçant la liste.",
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "documentId": {
      -              "description": "Pour le type `document` SEUL : l’identifiant d’un document du projet que TU peux lire (`list_documents`).",
      -              "maxLength": 200,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "key": {
      -              "description": "Ta clé STABLE pour ce livrable (ex. `pr-482`) : rejouer un ajout avec la même clé ne le duplique pas, il le MET À JOUR (c’est ainsi que tu passes une PR de `open` à `merged` : une `key` et un `state` suffisent alors, sans répéter l’URL). Sans clé, l’URL (normalisée), puis `(type, ref)`, désignent l’entrée.",
      -              "maxLength": 255,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "label": {
      -              "description": "Libellé court affiché.",
      -              "maxLength": 120,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "ref": {
      -              "description": "Référence courte affichée en monospace (sha, numéro de PR, identifiant de run).",
      -              "maxLength": 80,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "state": {
      -              "description": "L’état que TU DÉCLARES, vrai au moment de l’appel — OrgGen ne le vérifie jamais, l’humain voit « déclaré par l’agent ».",
      -              "enum": [
      -                "open",
      -                "merged",
      -                "closed",
      -                "succeeded",
      -                "failed",
      -                "superseded"
      -              ],
      -              "type": "string"
      -            },
      -            "type": {
      -              "description": "Le genre de livrable — énumération fermée.",
      -              "enum": [
      -                "commit",
      -                "pull_request",
      -                "deployment",
      -                "run",
      -                "document",
      -                "other"
      -              ],
      -              "type": "string"
      -            },
      -            "url": {
      -              "description": "Adresse http(s) ABSOLUE, sans identifiant ni mot de passe intégrés. OrgGen ne l’ouvre jamais : elle n’est qu’affichée.",
      -              "maxLength": 2048,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "type"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 20,
      -        "minItems": 1,
      -        "type": "array"
      -      },
      -      "parentTaskId": {
      -        "description": "Rattache cette tâche à son regroupement parent (« Fait partie de ») — une autre tâche de ce projet SANS `parentTaskId`, une US — dont elle devient une SOUS-TÂCHE. L’Épique, elle, est le BLOC (`cellId`) : la tâche parente n’est jamais l’Épique. Omis = tâche de premier niveau (une US). Profondeur limitée à DEUX niveaux : la cible ne peut pas être déjà elle-même une sous-tâche. Dans un LOT, la cible peut être créée dans le MÊME appel si elle apparaît AVANT (avec un `id` explicite).",
      -        "maxLength": 200,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "priority": {
      -        "enum": [
      -          "urgent",
      -          "high",
      -          "normal",
      -          "low"
      -        ],
      -        "type": "string"
      -      },
      -      "status": {
      -        "enum": [
      -          "todo",
      -          "doing",
      -          "done",
      -          "blocked"
      -        ],
      -        "type": "string"
      -      },
      -      "title": {
      -        "description": "Le libellé de la tâche, en une ligne.",
      -        "maxLength": 500,
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "title"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "items": {
      -      "additionalProperties": false,
      -      "properties": {
      -        "arbitrage": {
      -          "description": "Transforme cette tâche en ARBITRAGE — voir `update_task.arbitrageAction` pour la suite du cycle (validation/contestation par l’humain, prise en charge et clôture par l’agent). `cellId` omis : l’arbitrage reprend le bloc de sa tâche parente (`parentTaskId`), sinon il naît SANS SUJET (visible dans l’onglet Arbitrages, sur aucune carte) — la réponse le dit.",
      -          "properties": {
      -            "options": {
      -              "description": "Les réponses PRÉ-DÉFINIES — au moins deux, sinon il n’y a rien à choisir.",
      -              "items": {
      -                "additionalProperties": false,
      -                "properties": {
      -                  "id": {
      -                    "description": "Identifiant COURT de l’option — cité par `choose`, jamais affiché seul.",
      -                    "maxLength": 100,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "label": {
      -                    "description": "Le texte de la réponse proposée.",
      -                    "maxLength": 300,
      -                    "minLength": 1,
      -                    "type": "string"
      -                  },
      -                  "recommended": {
      -                    "anyOf": [
      -                      {
      -                        "additionalProperties": false,
      -                        "properties": {
      -                          "justification": {
      -                            "description": "Pourquoi cette option est recommandée — affichée à côté d’elle.",
      -                            "maxLength": 1000,
      -                            "minLength": 1,
      -                            "type": "string"
      -                          }
      -                        },
      -                        "required": [
      -                          "justification"
      -                        ],
      -                        "type": "object"
      -                      },
      -                      {
      -                        "type": "null"
      -                      }
      -                    ],
      -                    "description": "Marque CETTE option comme la recommandation de l’agent. Omis/`null` = aucune recommandation sur cette option (le cas normal)."
      -                  }
      -                },
      -                "required": [
      -                  "id",
      -                  "label"
      -                ],
      -                "type": "object"
      -              },
      -              "maxItems": 8,
      -              "minItems": 2,
      -              "type": "array"
      -            },
      -            "question": {
      -              "description": "La question posée à l’humain.",
      -              "maxLength": 2000,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "selectionMode": {
      -              "description": "Le mode de sélection humaine — `single` (une seule option, le défaut) ou `multiple` (cases à cocher, plusieurs options possibles). Posé une fois, jamais changé ensuite.",
      -              "enum": [
      -                "single",
      -                "multiple"
      -              ],
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "question",
      -            "options"
      -          ],
      -          "type": "object"
      -        },
      -        "assignees": {
      -          "description": "Responsables. Un identifiant ou un nom de personne du projet est RÉSOLU ; toute autre chaîne est conservée telle quelle comme désignation non résolue — jamais jetée.",
      -          "items": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 10,
      -          "type": "array"
      -        },
      -        "body": {
      -          "description": "Note détaillée, facultative.",
      -          "maxLength": 20000,
      -          "type": "string"
      -        },
      -        "cellId": {
      -          "description": "Le bloc (cellule) auquel la tâche se rattache — RECOMMANDÉ dans presque tous les cas : une tâche sans cellId n’apparaît sur AUCUNE carte du canevas, seulement dans la vue Tâches. Ne l’omets JAMAIS par réflexe quand un bloc évident existe déjà pour ce travail — réserve l’omission à une tâche réellement transverse, sans sujet unique (ex. « préparer la réunion mensuelle »). Omis = tâche « sans sujet ».",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "complexity": {
      -          "description": "Ordre de grandeur RELATIF en TEMPS HUMAIN : xs = moins d’une heure · s = quelques heures · m = une demi-journée à un jour · l = quelques jours · xl = à DÉCOUPER. Pose-la AVANT la prise du travail ; c’est une estimation, jamais une promesse. Sans valeur = non estimée.",
      -          "enum": [
      -            "xs",
      -            "s",
      -            "m",
      -            "l",
      -            "xl"
      -          ],
      -          "type": "string"
      -        },
      -        "dependsOn": {
      -          "description": "Ids d'AUTRES tâches de ce projet qui BLOQUENT celle-ci (distinct de `parentTaskId`, qui ORGANISE sans jamais bloquer). Chaque id doit exister dans ce projet — y compris dans ce MÊME lot, si la tâche référencée apparaît AVANT. Omis = aucune dépendance. Ne PAS confondre avec `status: 'blocked'` (un geste manuel, indépendant) : le blocage PAR DÉPENDANCE se lit via `list_tasks({fields:['dependsOn','openDependencyCount']})` ou le filtre `executable`.",
      -          "items": {
      -            "maxLength": 200,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 50,
      -          "type": "array"
      -        },
      -        "dueOn": {
      -          "description": "Échéance DATÉE (YYYY-MM-DD). Seule une date fait apparaître « en retard ».",
      -          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -          "type": "string"
      -        },
      -        "dueText": {
      -          "description": "Échéance en texte libre (« fin de semaine »). Conservée telle quelle et affichée, mais elle ne déclenche AUCUN calcul de retard : préfère `dueOn` quand la date est connue.",
      -          "maxLength": 200,
      -          "type": "string"
      -        },
      -        "externalId": {
      -          "description": "L'identifiant de cette tâche DANS le système d'origine (ex. \"ENG-1234\"). Va TOUJOURS avec `externalSource`.",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "externalSource": {
      -          "description": "Le système d'origine de cette tâche (ex. \"linear\", \"jira\", \"notion\"). Provenance affichée — ne remplace pas `id` comme clé d'idempotence. Va TOUJOURS avec `externalId`.",
      -          "maxLength": 60,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "id": {
      -          "description": "Identifiant fourni par l'appelant — une clé côté système externe (ticket, ligne d'import, clé de rejeu d'un agent). Omis = généré par OrgGen (tk_...). Si ce projet porte déjà une tâche avec cet identifiant, RIEN n'est écrit pour elle : elle est rendue telle quelle (alreadyExisted: true) — un appel rejoué ne duplique JAMAIS, et un contenu différent sur le second appel n'écrase pas le premier. Migration depuis un système externe : préfère le patron `\"<source>-<id-externe>\"` (ex. `\"linear-ENG-1234\"`) — c'est CE champ qui porte l'idempotence, `externalSource`/`externalId` ci-dessous ne font qu'afficher la provenance.",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "labels": {
      -          "items": {
      -            "maxLength": 60,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "maxItems": 20,
      -          "type": "array"
      -        },
      -        "links": {
      -          "description": "Les LIVRABLES de cette tâche (au plus 20) — commit, pull request, déploiement, run, document. Ils s’AJOUTENT ensuite un à un par `update_task.addLinks`, jamais en remplaçant la liste.",
      -          "items": {
      -            "additionalProperties": false,
      -            "properties": {
      -              "documentId": {
      -                "description": "Pour le type `document` SEUL : l’identifiant d’un document du projet que TU peux lire (`list_documents`).",
      -                "maxLength": 200,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "key": {
      -                "description": "Ta clé STABLE pour ce livrable (ex. `pr-482`) : rejouer un ajout avec la même clé ne le duplique pas, il le MET À JOUR (c’est ainsi que tu passes une PR de `open` à `merged` : une `key` et un `state` suffisent alors, sans répéter l’URL). Sans clé, l’URL (normalisée), puis `(type, ref)`, désignent l’entrée.",
      -                "maxLength": 255,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "label": {
      -                "description": "Libellé court affiché.",
      -                "maxLength": 120,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "ref": {
      -                "description": "Référence courte affichée en monospace (sha, numéro de PR, identifiant de run).",
      -                "maxLength": 80,
      -                "minLength": 1,
      -                "type": "string"
      -              },
      -              "state": {
      -                "description": "L’état que TU DÉCLARES, vrai au moment de l’appel — OrgGen ne le vérifie jamais, l’humain voit « déclaré par l’agent ».",
      -                "enum": [
      -                  "open",
      -                  "merged",
      -                  "closed",
      -                  "succeeded",
      -                  "failed",
      -                  "superseded"
      -                ],
      -                "type": "string"
      -              },
      -              "type": {
      -                "description": "Le genre de livrable — énumération fermée.",
      -                "enum": [
      -                  "commit",
      -                  "pull_request",
      -                  "deployment",
      -                  "run",
      -                  "document",
      -                  "other"
      -                ],
      -                "type": "string"
      -              },
      -              "url": {
      -                "description": "Adresse http(s) ABSOLUE, sans identifiant ni mot de passe intégrés. OrgGen ne l’ouvre jamais : elle n’est qu’affichée.",
      -                "maxLength": 2048,
      -                "minLength": 1,
      -                "type": "string"
      -              }
      -            },
      -            "required": [
      -              "type"
      -            ],
      -            "type": "object"
      -          },
      -          "maxItems": 20,
      -          "minItems": 1,
      -          "type": "array"
      -        },
      -        "parentTaskId": {
      -          "description": "Rattache cette tâche à son regroupement parent (« Fait partie de ») — une autre tâche de ce projet SANS `parentTaskId`, une US — dont elle devient une SOUS-TÂCHE. L’Épique, elle, est le BLOC (`cellId`) : la tâche parente n’est jamais l’Épique. Omis = tâche de premier niveau (une US). Profondeur limitée à DEUX niveaux : la cible ne peut pas être déjà elle-même une sous-tâche. Dans un LOT, la cible peut être créée dans le MÊME appel si elle apparaît AVANT (avec un `id` explicite).",
      -          "maxLength": 200,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "priority": {
      -          "enum": [
      -            "urgent",
      -            "high",
      -            "normal",
      -            "low"
      -          ],
      -          "type": "string"
      -        },
      -        "status": {
      -          "enum": [
      -            "todo",
      -            "doing",
      -            "done",
      -            "blocked"
      -          ],
      -          "type": "string"
      -        },
      -        "title": {
      -          "description": "Le libellé de la tâche, en une ligne.",
      -          "maxLength": 500,
      -          "minLength": 1,
      -          "type": "string"
      -        }
      -      },
      -      "required": [
      -        "title"
      -      ],
      -      "type": "object"
      -    },
      -    "maxItems": 100,
      -    "minItems": 1,
      -    "type": "array"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "arbitrage": {
      +        "description": "Transforme cette tâche en ARBITRAGE — voir `update_task.arbitrageAction` pour la suite du cycle (validation/contestation par l’humain, prise en charge et clôture par l’agent). `cellId` omis : l’arbitrage reprend le bloc de sa tâche parente (`parentTaskId`), sinon il naît SANS SUJET (visible dans l’onglet Arbitrages, sur aucune carte) — la réponse le dit.",
      +        "properties": {
      +          "options": {
      +            "description": "Les réponses PRÉ-DÉFINIES — au moins deux, sinon il n’y a rien à choisir.",
      +            "items": {
      +              "additionalProperties": false,
      +              "properties": {
      +                "id": {
      +                  "description": "Identifiant COURT de l’option — cité par `choose`, jamais affiché seul.",
      +                  "maxLength": 100,
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "label": {
      +                  "description": "Le texte de la réponse proposée.",
      +                  "maxLength": 300,
      +                  "minLength": 1,
      +                  "type": "string"
      +                },
      +                "recommended": {
      +                  "anyOf": [
      +                    {
      +                      "additionalProperties": false,
      +                      "properties": {
      +                        "justification": {
      +                          "description": "Pourquoi cette option est recommandée — affichée à côté d’elle.",
      +                          "maxLength": 1000,
      +                          "minLength": 1,
      +                          "type": "string"
      +                        }
      +                      },
      +                      "required": [
      +                        "justification"
      +                      ],
      +                      "type": "object"
      +                    },
      +                    {
      +                      "type": "null"
      +                    }
      +                  ],
      +                  "description": "Marque CETTE option comme la recommandation de l’agent. Omis/`null` = aucune recommandation sur cette option (le cas normal)."
      +                }
      +              },
      +              "required": [
      +                "id",
      +                "label"
      +              ],
      +              "type": "object"
      +            },
      +            "maxItems": 8,
      +            "minItems": 2,
      +            "type": "array"
      +          },
      +          "question": {
      +            "description": "La question posée à l’humain.",
      +            "maxLength": 2000,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "selectionMode": {
      +            "description": "Le mode de sélection humaine — `single` (une seule option, le défaut) ou `multiple` (cases à cocher, plusieurs options possibles). Posé une fois, jamais changé ensuite.",
      +            "enum": [
      +              "single",
      +              "multiple"
      +            ],
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "question",
      +          "options"
      +        ],
      +        "type": "object"
      +      },
      +      "assignees": {
      +        "description": "Responsables. Un identifiant ou un nom de personne du projet est RÉSOLU ; toute autre chaîne est conservée telle quelle comme désignation non résolue — jamais jetée.",
      +        "items": {
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 10,
      +        "type": "array"
      +      },
      +      "body": {
      +        "description": "Note détaillée, facultative.",
      +        "maxLength": 20000,
      +        "type": "string"
      +      },
      +      "cellId": {
      +        "description": "Le bloc (cellule) auquel la tâche se rattache — RECOMMANDÉ dans presque tous les cas : une tâche sans cellId n’apparaît sur AUCUNE carte du canevas, seulement dans la vue Tâches. L’omission est faite pour une tâche réellement transverse, sans sujet unique (ex. « préparer la réunion mensuelle »). Omis = tâche « sans sujet ».",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "complexity": {
      +        "description": "Ordre de grandeur RELATIF en TEMPS HUMAIN : xs = moins d’une heure · s = quelques heures · m = une demi-journée à un jour · l = quelques jours · xl = à DÉCOUPER. Elle s’estime AVANT la prise du travail ; c’est une estimation, jamais une promesse. Sans valeur = non estimée.",
      +        "enum": [
      +          "xs",
      +          "s",
      +          "m",
      +          "l",
      +          "xl"
      +        ],
      +        "type": "string"
      +      },
      +      "dependsOn": {
      +        "description": "Ids d'AUTRES tâches de ce projet qui BLOQUENT celle-ci (distinct de `parentTaskId`, qui ORGANISE sans jamais bloquer). Chaque id doit exister dans ce projet — y compris dans ce MÊME lot, si la tâche référencée apparaît AVANT. Omis = aucune dépendance. Distinct de `status: 'blocked'` (un geste manuel, indépendant) : le blocage PAR DÉPENDANCE se lit via `list_tasks({fields:['dependsOn','openDependencyCount']})` ou le filtre `executable`.",
      +        "items": {
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 50,
      +        "type": "array"
      +      },
      +      "dueOn": {
      +        "description": "Échéance DATÉE (YYYY-MM-DD). Seule une date fait apparaître « en retard ».",
      +        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +        "type": "string"
      +      },
      +      "dueText": {
      +        "description": "Échéance en texte libre (« fin de semaine »). Conservée telle quelle et affichée, mais elle ne déclenche AUCUN calcul de retard : `dueOn` porte la date quand elle est connue.",
      +        "maxLength": 200,
      +        "type": "string"
      +      },
      +      "externalId": {
      +        "description": "L'identifiant de cette tâche DANS le système d'origine (ex. \"ENG-1234\"). Toujours accompagné de `externalSource`.",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "externalSource": {
      +        "description": "Le système d'origine de cette tâche (ex. \"linear\", \"jira\", \"notion\"). Provenance affichée — ne remplace pas `id` comme clé d'idempotence. Toujours accompagnée de `externalId`.",
      +        "maxLength": 60,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "id": {
      +        "description": "Identifiant fourni par l'appelant — une clé côté système externe (ticket, ligne d'import, clé de rejeu d'un agent). Omis = généré par OrgGen (tk_...). Si ce projet porte déjà une tâche avec cet identifiant, RIEN n'est écrit pour elle : elle est rendue telle quelle (alreadyExisted: true) — un appel rejoué ne duplique JAMAIS, et un contenu différent sur le second appel n'écrase pas le premier. Migration depuis un système externe : le patron courant est `\"<source>-<id-externe>\"` (ex. `\"linear-ENG-1234\"`) — c'est CE champ qui porte l'idempotence, `externalSource`/`externalId` ci-dessous ne font qu'afficher la provenance.",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "labels": {
      +        "items": {
      +          "maxLength": 60,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 20,
      +        "type": "array"
      +      },
      +      "links": {
      +        "description": "Les LIVRABLES de cette tâche (au plus 20) — commit, pull request, déploiement, run, document. Ils s’AJOUTENT ensuite un à un par `update_task.addLinks`, jamais en remplaçant la liste.",
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "documentId": {
      +              "description": "Pour le type `document` SEUL : l’identifiant d’un document du projet que TU peux lire (`list_documents`).",
      +              "maxLength": 200,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "key": {
      +              "description": "Ta clé STABLE pour ce livrable (ex. `pr-482`) : rejouer un ajout avec la même clé ne le duplique pas, il le MET À JOUR (c’est ainsi que tu passes une PR de `open` à `merged` : une `key` et un `state` suffisent alors, sans répéter l’URL). Sans clé, l’URL (normalisée), puis `(type, ref)`, désignent l’entrée.",
      +              "maxLength": 255,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "label": {
      +              "description": "Libellé court affiché.",
      +              "maxLength": 120,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "ref": {
      +              "description": "Référence courte affichée en monospace (sha, numéro de PR, identifiant de run).",
      +              "maxLength": 80,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "state": {
      +              "description": "L’état que TU DÉCLARES, vrai au moment de l’appel — OrgGen ne le vérifie jamais, l’humain voit « déclaré par l’agent ».",
      +              "enum": [
      +                "open",
      +                "merged",
      +                "closed",
      +                "succeeded",
      +                "failed",
      +                "superseded"
      +              ],
      +              "type": "string"
      +            },
      +            "type": {
      +              "description": "Le genre de livrable — énumération fermée.",
      +              "enum": [
      +                "commit",
      +                "pull_request",
      +                "deployment",
      +                "run",
      +                "document",
      +                "other"
      +              ],
      +              "type": "string"
      +            },
      +            "url": {
      +              "description": "Adresse http(s) ABSOLUE, sans identifiant ni mot de passe intégrés. OrgGen ne l’ouvre jamais : elle n’est qu’affichée.",
      +              "maxLength": 2048,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "type"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 20,
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "parentTaskId": {
      +        "description": "Rattache cette tâche à son regroupement parent (« Fait partie de ») — une autre tâche de ce projet SANS `parentTaskId`, une US — dont elle devient une SOUS-TÂCHE. L’Épique, elle, est le BLOC (`cellId`) : la tâche parente n’est jamais l’Épique. Omis = tâche de premier niveau (une US). Profondeur limitée à DEUX niveaux : la cible ne peut pas être déjà elle-même une sous-tâche. Dans un LOT, la cible peut être créée dans le MÊME appel si elle apparaît AVANT (avec un `id` explicite).",
      +        "maxLength": 200,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "priority": {
      +        "enum": [
      +          "urgent",
      +          "high",
      +          "normal",
      +          "low"
      +        ],
      +        "type": "string"
      +      },
      +      "status": {
      +        "enum": [
      +          "todo",
      +          "doing",
      +          "done",
      +          "blocked"
      +        ],
      +        "type": "string"
      +      },
      +      "title": {
      +        "description": "Le libellé de la tâche, en une ligne.",
      +        "maxLength": 500,
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "title"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "items": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "arbitrage": {
      +          "description": "Transforme cette tâche en ARBITRAGE — voir `update_task.arbitrageAction` pour la suite du cycle (validation/contestation par l’humain, prise en charge et clôture par l’agent). `cellId` omis : l’arbitrage reprend le bloc de sa tâche parente (`parentTaskId`), sinon il naît SANS SUJET (visible dans l’onglet Arbitrages, sur aucune carte) — la réponse le dit.",
      +          "properties": {
      +            "options": {
      +              "description": "Les réponses PRÉ-DÉFINIES — au moins deux, sinon il n’y a rien à choisir.",
      +              "items": {
      +                "additionalProperties": false,
      +                "properties": {
      +                  "id": {
      +                    "description": "Identifiant COURT de l’option — cité par `choose`, jamais affiché seul.",
      +                    "maxLength": 100,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "label": {
      +                    "description": "Le texte de la réponse proposée.",
      +                    "maxLength": 300,
      +                    "minLength": 1,
      +                    "type": "string"
      +                  },
      +                  "recommended": {
      +                    "anyOf": [
      +                      {
      +                        "additionalProperties": false,
      +                        "properties": {
      +                          "justification": {
      +                            "description": "Pourquoi cette option est recommandée — affichée à côté d’elle.",
      +                            "maxLength": 1000,
      +                            "minLength": 1,
      +                            "type": "string"
      +                          }
      +                        },
      +                        "required": [
      +                          "justification"
      +                        ],
      +                        "type": "object"
      +                      },
      +                      {
      +                        "type": "null"
      +                      }
      +                    ],
      +                    "description": "Marque CETTE option comme la recommandation de l’agent. Omis/`null` = aucune recommandation sur cette option (le cas normal)."
      +                  }
      +                },
      +                "required": [
      +                  "id",
      +                  "label"
      +                ],
      +                "type": "object"
      +              },
      +              "maxItems": 8,
      +              "minItems": 2,
      +              "type": "array"
      +            },
      +            "question": {
      +              "description": "La question posée à l’humain.",
      +              "maxLength": 2000,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "selectionMode": {
      +              "description": "Le mode de sélection humaine — `single` (une seule option, le défaut) ou `multiple` (cases à cocher, plusieurs options possibles). Posé une fois, jamais changé ensuite.",
      +              "enum": [
      +                "single",
      +                "multiple"
      +              ],
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "question",
      +            "options"
      +          ],
      +          "type": "object"
      +        },
      +        "assignees": {
      +          "description": "Responsables. Un identifiant ou un nom de personne du projet est RÉSOLU ; toute autre chaîne est conservée telle quelle comme désignation non résolue — jamais jetée.",
      +          "items": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 10,
      +          "type": "array"
      +        },
      +        "body": {
      +          "description": "Note détaillée, facultative.",
      +          "maxLength": 20000,
      +          "type": "string"
      +        },
      +        "cellId": {
      +          "description": "Le bloc (cellule) auquel la tâche se rattache — RECOMMANDÉ dans presque tous les cas : une tâche sans cellId n’apparaît sur AUCUNE carte du canevas, seulement dans la vue Tâches. L’omission est faite pour une tâche réellement transverse, sans sujet unique (ex. « préparer la réunion mensuelle »). Omis = tâche « sans sujet ».",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "complexity": {
      +          "description": "Ordre de grandeur RELATIF en TEMPS HUMAIN : xs = moins d’une heure · s = quelques heures · m = une demi-journée à un jour · l = quelques jours · xl = à DÉCOUPER. Elle s’estime AVANT la prise du travail ; c’est une estimation, jamais une promesse. Sans valeur = non estimée.",
      +          "enum": [
      +            "xs",
      +            "s",
      +            "m",
      +            "l",
      +            "xl"
      +          ],
      +          "type": "string"
      +        },
      +        "dependsOn": {
      +          "description": "Ids d'AUTRES tâches de ce projet qui BLOQUENT celle-ci (distinct de `parentTaskId`, qui ORGANISE sans jamais bloquer). Chaque id doit exister dans ce projet — y compris dans ce MÊME lot, si la tâche référencée apparaît AVANT. Omis = aucune dépendance. Distinct de `status: 'blocked'` (un geste manuel, indépendant) : le blocage PAR DÉPENDANCE se lit via `list_tasks({fields:['dependsOn','openDependencyCount']})` ou le filtre `executable`.",
      +          "items": {
      +            "maxLength": 200,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 50,
      +          "type": "array"
      +        },
      +        "dueOn": {
      +          "description": "Échéance DATÉE (YYYY-MM-DD). Seule une date fait apparaître « en retard ».",
      +          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +          "type": "string"
      +        },
      +        "dueText": {
      +          "description": "Échéance en texte libre (« fin de semaine »). Conservée telle quelle et affichée, mais elle ne déclenche AUCUN calcul de retard : `dueOn` porte la date quand elle est connue.",
      +          "maxLength": 200,
      +          "type": "string"
      +        },
      +        "externalId": {
      +          "description": "L'identifiant de cette tâche DANS le système d'origine (ex. \"ENG-1234\"). Toujours accompagné de `externalSource`.",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "externalSource": {
      +          "description": "Le système d'origine de cette tâche (ex. \"linear\", \"jira\", \"notion\"). Provenance affichée — ne remplace pas `id` comme clé d'idempotence. Toujours accompagnée de `externalId`.",
      +          "maxLength": 60,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "id": {
      +          "description": "Identifiant fourni par l'appelant — une clé côté système externe (ticket, ligne d'import, clé de rejeu d'un agent). Omis = généré par OrgGen (tk_...). Si ce projet porte déjà une tâche avec cet identifiant, RIEN n'est écrit pour elle : elle est rendue telle quelle (alreadyExisted: true) — un appel rejoué ne duplique JAMAIS, et un contenu différent sur le second appel n'écrase pas le premier. Migration depuis un système externe : le patron courant est `\"<source>-<id-externe>\"` (ex. `\"linear-ENG-1234\"`) — c'est CE champ qui porte l'idempotence, `externalSource`/`externalId` ci-dessous ne font qu'afficher la provenance.",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "labels": {
      +          "items": {
      +            "maxLength": 60,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "maxItems": 20,
      +          "type": "array"
      +        },
      +        "links": {
      +          "description": "Les LIVRABLES de cette tâche (au plus 20) — commit, pull request, déploiement, run, document. Ils s’AJOUTENT ensuite un à un par `update_task.addLinks`, jamais en remplaçant la liste.",
      +          "items": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "documentId": {
      +                "description": "Pour le type `document` SEUL : l’identifiant d’un document du projet que TU peux lire (`list_documents`).",
      +                "maxLength": 200,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "key": {
      +                "description": "Ta clé STABLE pour ce livrable (ex. `pr-482`) : rejouer un ajout avec la même clé ne le duplique pas, il le MET À JOUR (c’est ainsi que tu passes une PR de `open` à `merged` : une `key` et un `state` suffisent alors, sans répéter l’URL). Sans clé, l’URL (normalisée), puis `(type, ref)`, désignent l’entrée.",
      +                "maxLength": 255,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "label": {
      +                "description": "Libellé court affiché.",
      +                "maxLength": 120,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "ref": {
      +                "description": "Référence courte affichée en monospace (sha, numéro de PR, identifiant de run).",
      +                "maxLength": 80,
      +                "minLength": 1,
      +                "type": "string"
      +              },
      +              "state": {
      +                "description": "L’état que TU DÉCLARES, vrai au moment de l’appel — OrgGen ne le vérifie jamais, l’humain voit « déclaré par l’agent ».",
      +                "enum": [
      +                  "open",
      +                  "merged",
      +                  "closed",
      +                  "succeeded",
      +                  "failed",
      +                  "superseded"
      +                ],
      +                "type": "string"
      +              },
      +              "type": {
      +                "description": "Le genre de livrable — énumération fermée.",
      +                "enum": [
      +                  "commit",
      +                  "pull_request",
      +                  "deployment",
      +                  "run",
      +                  "document",
      +                  "other"
      +                ],
      +                "type": "string"
      +              },
      +              "url": {
      +                "description": "Adresse http(s) ABSOLUE, sans identifiant ni mot de passe intégrés. OrgGen ne l’ouvre jamais : elle n’est qu’affichée.",
      +                "maxLength": 2048,
      +                "minLength": 1,
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "type"
      +            ],
      +            "type": "object"
      +          },
      +          "maxItems": 20,
      +          "minItems": 1,
      +          "type": "array"
      +        },
      +        "parentTaskId": {
      +          "description": "Rattache cette tâche à son regroupement parent (« Fait partie de ») — une autre tâche de ce projet SANS `parentTaskId`, une US — dont elle devient une SOUS-TÂCHE. L’Épique, elle, est le BLOC (`cellId`) : la tâche parente n’est jamais l’Épique. Omis = tâche de premier niveau (une US). Profondeur limitée à DEUX niveaux : la cible ne peut pas être déjà elle-même une sous-tâche. Dans un LOT, la cible peut être créée dans le MÊME appel si elle apparaît AVANT (avec un `id` explicite).",
      +          "maxLength": 200,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "priority": {
      +          "enum": [
      +            "urgent",
      +            "high",
      +            "normal",
      +            "low"
      +          ],
      +          "type": "string"
      +        },
      +        "status": {
      +          "enum": [
      +            "todo",
      +            "doing",
      +            "done",
      +            "blocked"
      +          ],
      +          "type": "string"
      +        },
      +        "title": {
      +          "description": "Le libellé de la tâche, en une ligne.",
      +          "maxLength": 500,
      +          "minLength": 1,
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "title"
      +      ],
      +      "type": "object"
      +    },
      +    "maxItems": 100,
      +    "minItems": 1,
      +    "type": "array"
      +  }
      +]
  4. First observed

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses replay semantics via `id`, `alreadyExisted`, generated ids, `batchUrl` behavior, arbitration inheritance, unresolved assignees, archived parents, and the fact that links are added later rather than replaced. These details materially change how an agent should call and interpret the tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is very long and dense, with many sentences repeating schema details and using emphasized caps for concepts already documented. It is front-loaded enough to state the core create behavior first, but overall the wording is not concise and some behavioral points are buried in long parenthetical passages.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex creation tool with no output schema, the description covers return shape, batch URL behavior, edge cases, and project targeting. An agent has enough information to understand both what will be created and what the response may contain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description reinforces important semantics such as `id` as a replay key and `dependsOn` versus `parentTaskId`, but most of that meaning is already present in the schema and it adds little new syntax or formatting guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: it creates one task as an object or up to 100 as an array. It distinguishes the two call forms and ties them to the same parameter model, so an agent can identify the tool without inspecting the schema first.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear contextual guidance: use the object form for one task, the array form for a batch, prefer `cellId` except for genuinely cross-cutting work, and use `update_task.addLinks` for later deliverables. The main gap is that it never names `import_tasks` as the alternative for bulk migration, even while discussing Linear/Jira/Notion imports.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.