Skip to main content
Glama

Server Details

Governed retail, FMCG, and CPG operational tools: runs, cases, approvals, audit-ready execution.

If you are the author of this connector, you can claim ownership by verifying the domain or GitHub account it belongs to. Claimed connector authors can inspect health checks, view analytics, and manage their listing.
Status
Healthy
Uptime
100.0% over 76 days
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL

TDQS

B3/5.0

Scored across 392 tools

Disambiguation2/5

With 392 tools spread across Clarity, Automations, Agents, Queues, Cases, Pulse, Notifications, and Files, many tools have near-identical purposes: completeClarityDocumentUpload vs completeClarityTeamDocumentUpload vs completeClarityOrganizationDocumentUpload, and getNotificationFeed vs listNotifications vs getNotificationBatch vs getUnreadNotificationCount, are easily confused. Landscape manipulation alone has createClarityLandscapeNode, createClarityProcessNode, proposeClarityLandscapeProcess, createClarityFolder, and setupClarityFoldersFromLandscape, whose boundaries only become clear after reading long descriptions. The descriptions are excellent individually, but an agent selecting among hundreds of overlapping endpoints will misselect.

Naming Consistency3/5

Most names follow camelCase verb-first patterns (createAgent, deleteQueue, updateCase), but the verb vocabulary is loose: get/list/read/retrieve are used interchangeably across resources, and some names are non-verb or odd (fileSuggestedClarityProcesses, setUpModule, postprocessClaritySnapshot, organizeClarityProcessLandscape). Domain prefixes are applied inconsistently — some tools carry a Clarity or Pulse prefix, comparable tools elsewhere do not.

Tool Count1/5

392 tools is an extreme mismatch for any coherent tool surface; even a multi-product platform this large should be split into per-domain servers. The sheer volume guarantees selection errors, context bloat, and duplicated surface area (e.g. three document-upload completers, four notification-read variants, many upload-URL creators).

Completeness4/5

Coverage is genuinely broad: CRUD and lifecycle operations exist for agents, revisions, automations, queues, cases, cases' json_data, rubrics, Clarity processes/snapshots/captures/landscape, Pulse dashboards, teams, invites, credentials, secrets, connections, skills, and files. A few gaps exist (e.g. some Pulse attachment and dashboard-version cleanup operations), but they are workaroundable and unlikely to block core workflows.

Available Tools

392 tools
acceptClarityLandscapeNodeAccept Clarity Landscape NodeAInspect

Accept a proposed area folder into the active process landscape, so it stops being a proposal and becomes part of the real structure (organization admin+). Only area folders can be accepted; a proposed process becomes real through assignClarityLandscapeNodeTeam instead. Re-accepting an already-active area is a no-op.

NameRequiredDescriptionDefault
orgIdYes
nodeIdYesThe proposed area folder to accept.

TDQS

A3.6/5.0
Behavior1/5

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

The description discloses useful context: organization admin+ permission, area-folder-only constraint, and no-op behavior on re-acceptance. However, it directly contradicts the annotation 'idempotentHint: false' by asserting that re-accepting an already-active area is a no-op, which implies idempotent behavior.

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

Conciseness5/5

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

The description is three sentences with no filler. It front-loads the core purpose, then adds the key constraint, the alternative tool, and the no-op edge case. Every sentence carries useful information.

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

Completeness2/5

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

The description covers purpose, permissions, constraints, and an alternative, but the idempotency contradiction makes the behavioral model unreliable for an agent. Additionally, orgId is left undocumented in both the schema and the description, leaving a meaningful gap for a two-parameter tool.

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 coverage is only 50%, with nodeId described but orgId not. The description adds meaning by clarifying that nodeId refers to a proposed area folder and that only area folders are valid, but it does not explain orgId beyond its parameter name, leaving part of the input semantics underspecified.

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 uses a specific verb ('Accept') and resource ('proposed area folder'), clearly explaining the state transition from proposal to active structure. It also distinguishes itself from assignClarityLandscapeNodeTeam, so an agent can tell them apart.

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool (accepting proposed area folders) and when not to ('proposed process becomes real through assignClarityLandscapeNodeTeam instead'). It also clarifies the no-op behavior for already-active areas, giving clear operational guidance.

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

acceptClarityProcessJoinAccept Clarity Process JoinBInspect

Accept a clarity interview invite link and gain process access.

NameRequiredDescriptionDefault
tokenYes

TDQS

B3.3/5.0
Behavior3/5

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

Annotations already indicate a non-read-only, non-idempotent mutation. The description adds that the outcome is gaining process access, but it does not disclose details like token consumption, failure behavior, or authorization requirements. This is acceptable but not rich.

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

Conciseness5/5

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

The description is a single efficient sentence that front-loads the action and states the outcome. There is no wasted wording or unnecessary repetition of the title.

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

Completeness3/5

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

For a simple tool with one required parameter and no output schema, the description provides the core idea but leaves parameter semantics and post-acceptance behavior unstated. It is minimally viable but not fully complete.

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

Parameters2/5

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

Schema description coverage is 0%, and the description never mentions the 'token' parameter directly. It only says 'invite link,' which gives vague context but does not explain that the token comes from the invite link, its format, or how to supply it.

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

Purpose4/5

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

The description uses a specific verb ('Accept') plus a resource ('a clarity interview invite link') and an outcome ('gain process access'), making the tool's purpose clear. It does not explicitly differentiate from sibling tools like getClarityProcessJoinInfo or createClarityInviteLink, but the action is distinct enough.

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

Usage Guidelines3/5

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

The description implies when to use the tool: when a user has a clarity interview invite link and wants to accept it. However, it provides no explicit guidance about alternatives, prerequisites, or cases where this tool should not be used.

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

acceptClarityTeamAssignmentSuggestionAccept Clarity Team Assignment SuggestionAInspect

Accept a pending Process Landscape team-assignment suggestion and durably assign the suggested team (manager+).

NameRequiredDescriptionDefault
nodeIdYes
suggestionIdYes

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already indicate this is not read-only, and the description adds that the assignment is 'durable', clarifying persistence and mutation. It does not disclose whether the accepted suggestion is consumed, whether a previous assignment is overwritten, or any other side effects. Given the annotations, this is adequate but not rich.

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

Conciseness5/5

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

The description is a single, tightly worded sentence with no filler, tautology, or repetition of the tool name. It front-loads the action and then gives the essential object and outcome, making it easy to scan.

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

Completeness3/5

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

For a simple two-parameter mutation, the description covers the core purpose and effect, and the annotations cover the read-only/destructive expectations. However, it does not explain how to obtain a valid nodeId or suggestionId, nor what happens after acceptance. An agent would likely need external knowledge or sibling tools to invoke this correctly.

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

Parameters2/5

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

Schema description coverage is 0%, and the description does not explain what nodeId or suggestionId refer to beyond their self-descriptive names. It does not clarify where these IDs come from or how they relate to the 'suggested team' mentioned in the description. The description fails to compensate for the complete lack of parameter documentation.

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 uses a specific verb ('Accept'), identifies the exact resource ('pending Process Landscape team-assignment suggestion'), and states the resulting effect ('durably assign the suggested team'). It clearly differentiates this from sibling tools like dismissClarityTeamAssignmentSuggestion and assignClarityLandscapeNodeTeam by focusing on accepting an existing suggestion rather than dismissing or directly assigning.

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

Usage Guidelines3/5

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

The description implies the tool is for confirming an already-pending team assignment suggestion, which gives some contextual usage guidance. However, it does not explicitly state when to choose this tool over alternatives, nor does it mention related tools such as dismissClarityTeamAssignmentSuggestion or how pending suggestions are discovered. The usage condition is mostly left to inference.

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

acceptRevisionGenerationAccept Revision GenerationAInspect

Accept the reviewed generated configuration and complete the builder run. The saved draft is not activated.

NameRequiredDescriptionDefault
build_idYesThe revision identifier.
builder_run_idYesThe builder run returned by generation or status, belonging to this revision.
expected_started_atYesCopy started_at from the status being reviewed. Each prompt has its own builder run ID; stale review identities return 409.

TDQS

A4/5.0
Behavior4/5

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

Annotations already indicate a non-read-only, non-destructive, non-idempotent mutation. The description adds meaningful behavioral context by stating the acceptance completes the builder run and that the saved draft is not activated, preventing a likely misinterpretation that acceptance equals activation. No contradiction with annotations was found.

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

Conciseness5/5

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

Two short sentences with no filler. The primary action and outcome are front-loaded, and the critical non-activation caveat is placed second without redundancy.

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

Completeness4/5

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

For a three-parameter tool with fully documented schema properties, the description plus schema provides sufficient guidance for the agent to call it correctly. The one gap is the lack of explicit procedural context about when in the generation/review workflow acceptance should occur, though the description and parameter descriptions imply it well enough.

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 schema already documents all three parameters, including the important guidance on expected_started_at and stale review identities returning 409. The description itself adds no parameter-level meaning, so the baseline of 3 is appropriate.

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 states a specific verb ('Accept') and resource ('reviewed generated configuration') and adds the outcome 'complete the builder run.' It also differentiates from related siblings like activateAutomationRevision by explicitly noting the saved draft is not activated, and from declineRevisionGeneration via the accept/decline contrast.

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

Usage Guidelines3/5

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

The context is implied: use this after reviewing a generated configuration and wanting to complete the builder run. However, it does not explicitly name alternatives such as declineRevisionGeneration, cancelBuilderRun, or resumeBuilderRun, nor does it provide clear when-not-to-use guidance beyond the non-activation clarification.

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

addAutomationAgentAdd Automation AgentAInspect

Add an agent to an automation on a team that is on the Automations workspace, with or without revisions — membership is not versioned. The agent must not already belong to another automation; on a team that changes its automations by revision it cannot be moved between them at all, because the revisions binding it are immutable. Adding an agent that is already a member succeeds unchanged.

NameRequiredDescriptionDefault
agent_idYesAgent ID
automation_idYesAutomation ID

TDQS

A4.1/5.0
Behavior4/5

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

Adds real behavioral context beyond the annotations: preconditions (no existing automation membership), immutability of revision bindings, and the re-add-succeeds-unchanged outcome, which is a useful edge case. It does not state error behavior, required permissions, or side effects beyond membership.

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

Conciseness4/5

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

Purpose and scope are front-loaded in the first clause, and every sentence carries substantive content (preconditions, immutability, idempotent-like outcome). However, the em-dash-heavy, run-on phrasing makes it denser than necessary and slightly harder to scan.

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

Completeness4/5

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

For a two-parameter mutation with annotations covering safety hints and no output schema, the description covers the important edge cases and preconditions. Remaining gaps (permission requirements, failure modes) are minor for a tool of this complexity.

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% for the two UUID parameters, so the schema already carries the full parameter documentation. The description refers to agents and automations conceptually but adds no format, lookup, or constraint detail beyond the schema.

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?

States a specific verb (add) and resource (agent to an automation) with scope qualifiers (team on the Automations workspace). It also distinguishes itself from revision-scoped siblings by explicitly stating 'membership is not versioned', contrasting with tools like setAutomationRevisionAgent.

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?

Gives clear preconditions: the agent must not already belong to another automation, and on revision-based teams it cannot be moved between automations. It does not name an explicit alternative tool (e.g., setAutomationRevisionAgent) for the revision case, so routing is inferred rather than stated.

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

addAutomationQueueAdd Automation QueueAInspect

Add a queue to an automation on a team that is on the Automations workspace, with or without revisions — membership is not versioned. The queue must not already belong to another automation; on a team that changes its automations by revision it cannot be moved between them at all, because the revisions binding it are immutable. Adding a queue that is already a member succeeds unchanged.

NameRequiredDescriptionDefault
automation_idYesAutomation ID
case_queue_idYesQueue ID

TDQS

A3.9/5.0
Behavior4/5

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

Annotations declare readOnlyHint=false, idempotentHint=false, destructiveHint=false, so mutation semantics are partly covered. The description adds genuinely non-obvious behavior: membership is not versioned, revisions bind immutably, and re-adding an existing member succeeds unchanged — context the annotations cannot convey.

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

Conciseness4/5

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

Front-loaded with the core action, then the constraints. It is dense — several ideas packed into two long sentences — but each clause (non-versioned membership, immutability, re-add behavior) carries real information, so little is wasted.

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

Completeness4/5

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

For a two-parameter mutation with no output schema, the description covers the key calling constraints and edge cases (existing membership, revision-bound queues). It does not describe error/failure modes or required permissions, a minor gap given the annotation coverage.

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% with only two UUID parameters (automation_id, case_queue_id), so the schema already carries the semantics. The description adds no format, source, or constraint detail for the individual parameters, so the documented baseline of 3 applies.

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?

States a specific verb (add) and resource (queue to an automation) plus the constraining scope (team on the Automations workspace, versioned vs. revisioned). This lets an agent distinguish it from setAutomationRevisionQueue / removeAutomationQueue without opening a schema.

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

Usage Guidelines3/5

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

The description gives preconditions (queue must not already belong to another automation; on revision-based teams it cannot be moved between automations) but never names an alternative sibling tool or explicitly says when to prefer setAutomationRevisionQueue over this one. Usage is implied through constraints rather than routed.

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

addClarityLandscapeNodePersonAdd Clarity Landscape Node PersonAInspect

Add a person involved in the process behind a process landscape node. Name only records a placeholder; supplying an email also gives that person access to the process and emails them an invitation, so only pass an email the user asked you to invite.

NameRequiredDescriptionDefault
nameNo
roleNo
emailNo
orgIdYes
nodeIdYesA process landscape node that is linked to a real process.
teamIdNo
teamRoleNo

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already flag a non-read-only, non-idempotent, open-world mutation, but the description adds material side-effect detail beyond them: supplying an email grants the person access and dispatches an invitation email. This is exactly the kind of behavioral consequence the agent needs, though it omits team/role effects.

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

Conciseness5/5

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

Two tightly written sentences with the core side-effect warning placed prominently. Every clause earns its place with no redundancy.

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

Completeness3/5

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

For a 7-parameter mutation tool with only 14% schema coverage and no output schema, the description covers the invite/access behavior but leaves role, teamId, and teamRole entirely unaddressed, so it is adequate but incomplete.

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 14%, so the description carries most of the burden. It explains the semantics of name and email well, but role, teamId, and teamRole are undocumented in both the schema and the description, leaving a meaningful gap.

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

Purpose4/5

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

The description states a specific verb+resource: adding a person to the process behind a landscape node. It is clear what the tool does, though it does not explicitly distinguish itself from siblings like batchAddClarityLandscapeNodePeople or updateClarityLandscapeNodePerson.

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 an explicit conditional constraint: a name alone records a placeholder, while an email grants process access and sends an invite, so only pass an email the user asked to invite. It lacks explicit routing to sibling alternatives (e.g. the batch variant), but the usage condition is clear.

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

addConfigFieldAdd Config FieldAInspect

Add a Policy question to this automation. Its key is custom_ plus the label in snake_case, with _2, _3 and so on appended when the key is taken, and it is placed at the end of its section. A module template reinstall never changes a field added here.

NameRequiredDescriptionDefault
keyNoCode for the field, unique within the automation; derived from the label when left out
typeYesValue type; compound and sourcePointer are template-only
labelYesShort name for the field, shown as its row heading
rolesNoKeys of the process roles whose holders answer this question; empty means anyone
columnsNoRequired for table, refused otherwise
exampleNoAn example answer to the question; left out or null for none
optionsNoRequired for select and multiSelect, refused otherwise
sectionNoSection to add the field to, or null for none
bindingsNoHow the value reaches the automation (context, tool)
guidanceNoWhat to fill in for the question, in plain sentences; left out or null for none
questionYesThe setup question asked for this field
fill_modeNoHow the field is filled (interview, setup)interview
automation_idYesThe automation's unique identifier

TDQS

A3.9/5.0
Behavior4/5

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

Annotations cover the safety profile (readOnlyHint=false, idempotentHint=false, destructiveHint=false), and the description adds real context on top: the key-naming/collision scheme and, notably, that a template reinstall won't overwrite fields added here. That persistence guarantee is the kind of behavioral trait annotations cannot express.

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

Conciseness5/5

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

Two sentences, front-loaded with the core action, then the naming and placement rules. No filler or redundancy; every clause carries information.

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

Completeness3/5

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

For a 13-parameter create tool with no output schema, the description omits which fields are required (automation_id, label, question, type) and how the returned field is identified. The rich schema compensates, but a create operation would benefit from a note on required inputs and the effect on the automation.

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 elaborates the key derivation (custom_ prefix, snake_case label, _2/_3 suffix on collision), which slightly amplifies the schema's 'derived from the label when left out', but leaves the other 12 parameters entirely to the schema.

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 states a specific verb and resource ('Add a Policy question to this automation') and clearly delimits the tool from siblings like updateConfigField, listConfigFields, and addConfigSection. An agent can identify exactly what this creates without opening the schema.

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

Usage Guidelines3/5

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

It implies the context (adding a new field to an existing automation) and states a placement rule, but never says when to prefer this over updateConfigField or how it relates to addConfigSection. No explicit alternatives or when-not-to-use guidance is given.

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

addConfigSectionAdd Config SectionAInspect

Add an empty section to this automation's Policy, last or right after after_key. Its key is the name in lowercase words joined by hyphens, with -2, -3 and so on appended when the key is taken. A name another section has, ignoring case, is refused with a 409. A module template reinstall never changes a section added here.

NameRequiredDescriptionDefault
nameYesThe section heading shown on the Policy screen, unique within the automation ignoring case
after_keyNoKey of the section to place the new one right after; omitted, it goes last
automation_idYesThe automation's unique identifier

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already mark this as a non-read-only, non-idempotent, non-destructive mutation. The description adds real value beyond them: the deterministic key derivation (lowercase-hyphen with -2/-3 suffixes when taken), the case-insensitive 409 refusal, and the guarantee that a module template reinstall leaves the section intact.

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

Conciseness4/5

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

Three sentences, front-loaded with the core action and placement, then the key-generation and conflict rules. Dense but each sentence carries distinct information; no filler.

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

Completeness4/5

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

For a mutation with no output schema and full param documentation, the description covers the key edge cases an agent needs: name collisions, generated key format, and persistence across template reinstall. It omits return shape and auth requirements, but those are minor given no output schema exists.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description explains the name-to-key transformation and the conflict behavior, which the schema does not. The after_key fallback ('omitted, it goes last') is also clarified, adding meaning beyond the raw schema.

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

Purpose4/5

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

States a specific verb (add) and resource (empty section) scoped to the automation's Policy, with placement semantics. It is clearly distinguishable from addConfigField and renameConfigSection by resource, though it never names a sibling explicitly.

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

Usage Guidelines3/5

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

The description implies usage through the placement and key-conflict rules, but it never states when to choose this over addConfigField, renameConfigSection, or reorderConfigSections, nor any prerequisite conditions. Usage is inferable rather than guided.

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

answerPulseDashboardQuestionAnswer Pulse Dashboard QuestionAInspect

Answer a pending question the Duvo Pulse agent asked and resume the paused run (creator or team editors). Use the toolCallId from the dashboard's message transcript.

NameRequiredDescriptionDefault
answersYes
artifactIdYes
toolCallIdYes

TDQS

A3.9/5.0
Behavior4/5

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

With annotations already marking this as non-read-only and non-destructive, the description adds useful behavioral context: the tool resumes a paused run and is restricted to creators/team editors. It also explains that toolCallId comes from the dashboard transcript. No contradiction with annotations is present.

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

Conciseness5/5

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

The description is a single, front-loaded sentence with no filler. It states the action, the governing context, the allowed actors, and the key parameter source in an economical way.

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

Completeness2/5

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

While the description is clear about the tool's purpose and auth scope, it leaves two of three required parameters underspecified in a schema with zero descriptions. There is no output schema, so the description carries the full burden, but it does not explain what artifactId refers to or how the answers object should be populated.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate for undocumented parameters. It only explains toolCallId's origin. artifactId and the structure/semantics of the answers object are left undefined, leaving an agent to guess what keys and values the answers object expects.

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 states a specific verb and resource: 'Answer a pending question the Duvo Pulse agent asked' and clearly identifies the follow-up effect: 'resume the paused run'. This is not a tautology and is specific enough to differentiate from generic tools like respondToHumanRequest or sendPulseDashboardMessage.

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?

The description provides clear context on when to use the tool: only for pending Duvo Pulse agent questions on a paused run, and only for 'creator or team editors'. It also gives a concrete source for toolCallId. It stops short of explicitly naming alternatives or saying when not to use it, so it does not reach a 5.

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

approveAutomationProposalApprove Automation ProposalAInspect

Approve the automation proposal of a Module automation being set up, the same as the setup's Approve and build in the web app: it opens an Ask Duvo conversation that reads the proposal and the Policy, proposes which Agents, Queues and dashboards change, makes the changes once the user agrees there, and finishes the setup. Give the user the conversation's url; they answer Duvo's plan in it. proposal_snapshot_id, when given, must be the live proposal. A build already started is returned with status already_started rather than started twice. Refused with 409 when there is no live proposal, required Policy questions are open, or Ask Duvo isn't available to the team, and with 403 below Builder. Confirm with the user before calling: approving starts the build.

NameRequiredDescriptionDefault
automation_idYesAutomation ID
proposal_snapshot_idNoThe automation proposal being approved. Must be the live proposal; leave out to approve whichever proposal is live.

TDQS

A4.8/5.0
Behavior5/5

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

Goes well beyond the annotations (readOnly=false, destructive=false, idempotent=false, openWorld=false) by disclosing role requirements (Builder), HTTP-level refusal conditions (409/403), the safe retry behavior ('already_started' rather than starting twice), and that the actual mutations happen inside a user-mediated Ask Duvo conversation. This is the permission, side-effect and failure-mode context an agent needs before triggering a build.

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

Conciseness4/5

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

Front-loaded with the purpose and the web-app analogue, then layers behavior, parameters, errors and the confirmation warning in a sensible order. Sentences are long and dense, especially the first, but every clause carries information an agent would otherwise have to guess.

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 mutation tool with no output schema and no annotation coverage of failure modes, the description supplies the conversational flow, the returned `url` handoff, the `already_started` status, authorization thresholds and error codes. Nothing material is missing for correct invocation.

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

Parameters4/5

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

Schema coverage is 100%, so both UUID parameters are already documented; the description adds the operational constraint that `proposal_snapshot_id` must be the live proposal and that omitting it defaults to whichever is live, plus the consequence (409) when no live proposal exists. Marginal value over the schema, but real.

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?

States a specific verb and resource ('Approve the automation proposal of a Module automation being set up') and anchors it to the web-app equivalent ('the same as the setup's Approve and build'), which distinguishes it from siblings like generateAutomationProposal or buildClarityAutomation. The downstream effect (opens Ask Duvo conversation that proposes and applies changes, then finishes the setup) makes the action unambiguous.

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

Usage Guidelines5/5

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

Explicitly instructs 'Confirm with the user before calling: approving starts the build' and tells the agent what to do with the returned conversation `url`. It also enumerates when the call will fail (409 when no live proposal, open Policy questions, or Ask Duvo unavailable; 403 below Builder) and when to pass or omit `proposal_snapshot_id`.

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

assignCaseLabelsAssign Case LabelsBInspect

Assign one or more labels to a case. Creates the labels on the queue if they don't already exist.

NameRequiredDescriptionDefault
labelsYes
case_idYesThe case's unique identifier
queue_idYesThe queue's unique identifier

TDQS

B3.4/5.0
Behavior3/5

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

The description adds a behavioral detail beyond the annotations: labels are created if they don't already exist. While the annotations already indicate the tool is not read-only, this note clarifies a side effect but does not cover other aspects like error handling or idempotency.

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

Conciseness5/5

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

The description is a single, concise sentence that immediately states the action and the key side effect. It is well-structured with no redundant or extraneous information, making it easy to parse.

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

Completeness3/5

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

The description covers the primary action and a notable side effect, but it omits details about the return value or any error conditions. Since no output schema is provided, the agent is left without knowledge of what the tool returns, which is a gap for a complete understanding.

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

Parameters2/5

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

The schema describes queue_id and case_id, but the labels parameter lacks a description. The tool description does not compensate, offering no explanation of what 'labels' entails beyond its name. This leaves ambiguity for the labels structure, especially since it contains nested key-value pairs.

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 clearly states the action: 'Assign one or more labels to a case' and adds a specific side effect about creating missing labels. It distinctively describes the tool's function without ambiguity, and the name aligns well with the description.

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

Usage Guidelines2/5

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

The description does not provide explicit guidance on when to use this tool versus alternatives like unlinkCaseLabels or updateCase. It merely states what the tool does, leaving the agent to infer the appropriate context from the tool name and sibling list.

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

assignClarityExtraCaptureRequestAssign Clarity Extra Capture RequestA
Destructive
Inspect

Assign (or unassign, with user_id: null) a team member to fulfil an extra-capture request. Restricted to Lead Builders and above.

NameRequiredDescriptionDefault
user_idYesTeam member to assign, or null to unassign
process_idYesThe clarity process id
request_idYesThe extra-capture-request id
transformation_proposal_idYesThe automation proposal id

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare the mutation/destructive/idempotent profile, so the added value here is the authorization requirement and the dual assign/unassign behavior, both of which go beyond structured fields. It stops short of explaining what the destructiveHint actually means (e.g., whether an existing assignee is replaced) or how failures surface.

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

Conciseness5/5

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

Two short sentences with the core action and the null-unassign variant front-loaded; the permission caveat follows without padding. Every clause earns its place.

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

Completeness4/5

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

For a four-param mutation tool with full schema coverage and annotations supplying the safety profile, the description contributes the missing auth requirement and the assign/unassign duality. Return behavior and the effect on any prior assignee remain unstated, but no output schema exists to fill that gap.

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 coverage is 100% and each parameter is already documented, including 'null to unassign' for user_id, so the description adds no syntax or format meaning beyond the schema. Baseline 3 applies when the schema carries the full parameter burden.

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

Purpose4/5

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

The description names a specific verb (assign/unassign), its resource (extra-capture request), and its subject (a team member), so the action is unambiguous. It does not, however, distinguish itself from the near-identical sibling assignClarityLandscapeCaptureRequest, which an agent could easily confuse for the same operation.

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

Usage Guidelines3/5

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

It concisely explains the unassign case via `user_id: null` and states the permission gate 'Lead Builders and above', which is real usage context. It offers no explicit when-to-use versus the Landscape or Team assignment siblings, leaving the routing decision to inference.

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

assignClarityLandscapeNodeTeamAssign Clarity Landscape Node TeamA
DestructiveIdempotent
Inspect

Set the owning team of a process in the process landscape (organization admin+). On a proposed process this accepts the proposal and creates the real process for that team; on an existing process it moves the process, its captures and its brief to another team.

NameRequiredDescriptionDefault
orgIdYes
intentNoPass "accept-proposal" when the node is expected to still be a proposed process; the call then fails if someone already accepted it, instead of silently moving a real process.
nodeIdYesThe process node whose owning team changes.
teamIdYesThe team that owns the process from now on. A process always belongs to a team, so null is rejected.

TDQS

A4/5.0
Behavior4/5

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

Adds meaningful context beyond the annotations: the admin+ permission requirement, the side effect that a proposal is accepted and a real process is created, and that a move also relocates the process's captures and brief. That discloses scope of mutation well, though it does not address reversibility or failure modes beyond what the schema states.

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

Conciseness5/5

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

Two dense sentences, front-loaded with the action, then the permission gate, then the two behavioral branches. No filler or repetition.

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

Completeness4/5

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

For a destructive, idempotent mutation with no output schema, the definition covers permissions, side effects, and outcome branching, which is what an agent needs before calling it. Minor omissions (no note on reversibility or what a successful response yields) keep it short of a 5.

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 75% and the descriptions already cover intent semantics (the fail-if-already-accepted behavior) and teamId's null rejection. The description implies the 'accept-proposal' path but never names parameters or adds syntax beyond the schema, so it sits at the baseline.

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

Purpose4/5

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

States a specific verb+resource: setting the owning team of a process in the process landscape, and spells out the two distinct outcomes (accepting a proposal vs. moving an existing process). This is clear and concrete, but no sibling tool is named (e.g., setClarityLandscapeNodePlacement, acceptClarityLandscapeNode), so differentiation is implied rather than explicit.

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?

Provides a real precondition (organization admin+) and explains that behavior branches on whether the node is still a proposed process or an already-accepted one, which tells an agent when each mode applies. It never explicitly routes the agent away from alternatives or states when not to use this tool.

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

assignClarityProcessLabelsAssign Clarity Process LabelsCInspect

Assign process tags to a process.

NameRequiredDescriptionDefault
idYes
labelsNo
labelIdsNo

TDQS

C2.6/5.0
Behavior2/5

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

Annotations indicate readOnlyHint=false, idempotentHint=false, and destructiveHint=false, so the description must explain side effects. It does not disclose whether assigning labels replaces existing process labels or appends to them, whether labels are created inline or referenced by ID, or what the response looks like. The word 'assign' only signals mutation without adding meaningful behavioral detail.

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

Conciseness4/5

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

The description is a single sentence with no filler, making it easy to scan and front-loaded with the main action. It is concise, though it is too sparse to be considered a fully developed definition.

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

Completeness2/5

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

For a three-parameter mutation tool with no output schema and no parameter descriptions, one sentence is not enough. It does not state whether labels and labelIds are alternatives, whether the operation replaces or adds tags, or what happens when only id is supplied, leaving agents unable to invoke it confidently.

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

Parameters1/5

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

The schema has 0% description coverage and the description adds no parameter-level meaning. It leaves the crucial labels-vs-labelIds distinction ambiguous, does not mention colorHue, and does not clarify that id is required while labels and labelIds are optional in the schema.

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

Purpose4/5

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

The description uses a specific verb ('assign') and identifies both the object ('process tags'/'labels') and the target ('a process'), so the core operation is clear. It does not explicitly distinguish itself from close siblings such as createClarityProcessLabel or assignClarityLandscapeNodeTeam, but it is not a tautology or misleading.

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

Usage Guidelines2/5

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

No guidance is given about when to use this tool instead of alternatives like assignCaseLabels, assignClarityExtraCaptureRequest, or unlinkClarityProcessLabels. The sentence merely restates the action and provides no conditions, exclusions, or selection criteria.

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

assignPolicyInterviewAssign Policy InterviewAInspect

Assign a Policy interview: a Clarity voice interview covering the automation's open Policy questions, whose answers are written back onto them. Pass invited_email to email it to someone, and context to say who they are; leave invited_email out to create an unassigned interview slot. This emails a real person: name them, give the exact address and say what the interview covers, and call this only after the user says yes. Use only an address the user gave you. Administrators and above only.

NameRequiredDescriptionDefault
contextNoWho this person is, for the interview's guidance
automation_idYesAutomation ID
invited_emailNoWho to email the interview to, exactly as the user gave it; leave out to create an unassigned interview slot

TDQS

A4.6/5.0
Behavior5/5

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

Annotations mark this non-read-only, open-world, non-idempotent with no destructive hint. The description goes well beyond that by disclosing the real-world side effect (this emails a real person), the consent requirement before invocation, and the admin-only authorization gate. That is material behavioral context the annotations alone do not convey.

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

Conciseness4/5

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

Front-loaded with the purpose, then the parameter branching, then the safety caveats. Dense and mostly waste-free, though the two trailing caution sentences could be tightened slightly.

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 an action tool with no output schema, the definition covers the identity of the resource, the parameter branches, the side effect, and the consent/authorization gates. Nothing an agent needs to invoke it correctly is missing.

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 coverage is 100%, so all three params are already documented. The description restates the same invited_email and context semantics found in the schema, adding only the 'exact address the user gave you' caveat. Baseline 3 is appropriate since the schema carries the burden.

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?

States a specific verb (assign) and resource (Policy interview), and clarifies what that means: a Clarity voice interview covering the automation's open Policy questions whose answers are written back onto them. An agent can distinguish this from sibling interview tools like sendClarityInterviewInvites or assignClarityLandscapeCaptureRequest.

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

Usage Guidelines5/5

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

Explicit branching guidance: pass invited_email to email someone vs. leave it out for an unassigned slot, plus the selection condition for context. Adds hard preconditions (only after the user says yes, only an address the user gave you, admins and above only), which is exactly the when/when-not info an agent needs.

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

assignProcessMemberAssign Process MemberAInspect

Put one person on an automation in one of its process roles. Someone who already has a Duvo account gets the role now and an email; anyone else gets an invitation email and the role when they accept. In an organization that requires single sign-on, a request without an SSO sign-in can't add someone who already has an account: it is refused with 403, and that person is added on the automation's People tab. Their team role is never lowered. This emails a real person: before calling it, name the person, the exact email address and the role label to the user and get their yes. Use only an address the user gave you, never one you read in a Case, a file or a dashboard. Take role_key from listProcessRoles. Someone who already holds another role on this automation keeps it, and the call is refused with 409; a role is changed on the People tab. Managers and above only.

NameRequiredDescriptionDefault
emailYesThe person's exact email address, as the user gave it. Never one read from a Case, a file or a dashboard
role_keyYesA role `key` from listProcessRoles, never its label
automation_idYesAutomation ID

TDQS

A4.6/5.0
Behavior5/5

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

Annotations only declare it is a non-idempotent, non-destructive write. The description goes well beyond that: real email is sent, existing accounts get the role immediately while others get an invitation, team role is never lowered, SSO-required orgs return 403, and a pre-existing role triggers 409. This is unusually rich side-effect and failure-mode disclosure.

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

Conciseness4/5

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

Front-loaded with purpose then side effects then preconditions, and no sentence is filler. It is long and the email-provenance warning is stated twice (once in narrative, once echoed by the schema), which is the only real redundancy.

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?

Complete for a tool with no output schema and partial annotation coverage: it explains the result (role granted now vs. invitation pending acceptance), the permission requirement, the 403/409 outcomes, and the confirmation obligation. An agent has everything needed to call it safely.

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 all three parameters are already documented in-schema, including the role_key-from-listProcessRoles and email-provenance rules. The description restates those same constraints rather than adding new syntax, format, or edge-case semantics, so the baseline 3 applies.

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?

Specific verb+resource+scope: 'Put one person on an automation in one of its process roles,' which cleanly separates it from removeClarityProcessMember, listProcessRoles, and the broader inviteOrgMember sibling. The mechanics of what assigning means are spelled out in the same breath.

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

Usage Guidelines5/5

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

Explicit preconditions and alternatives: take role_key from listProcessRoles, managers-and-above permission gate, mandatory user confirmation before calling, and it routes to the People tab when the call is refused. It also states which email addresses are eligible versus which are off-limits.

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

attachPulseDashboardConnectionAttach Pulse Dashboard ConnectionBInspect

Attach one of your connections (data sources) to a Duvo Pulse dashboard so the agent can use its tools (requires edit access).

NameRequiredDescriptionDefault
artifactIdYes
connection_idYes

TDQS

B3.4/5.0
Behavior3/5

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

Annotations declare readOnlyHint=false, destructiveHint=false, and idempotentHint=false, so the agent knows this is a non-read, non-idempotent mutation. The description adds the edit-access requirement and the effect of enabling the agent's tools on the dashboard, which is useful context. It does not disclose whether attaching is additive vs. replacing existing connections, but it is not misleading.

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

Conciseness4/5

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

One sentence, front-loaded with the action and target, and the parenthetical clarifications ('data sources', 'requires edit access') earn their place. It is efficient without being terse to the point of ambiguity.

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

Completeness3/5

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

For a 2-param mutation with no output schema, the description covers the core action and the key prerequisite (edit access). It falls short of complete because it doesn't state whether the attachment replaces or appends to existing connections, and there is no mention of validation effects or error conditions. Still adequate for an agent to attempt the call correctly.

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 0%, but the parameter names are strongly self-descriptive: artifactId clearly refers to the dashboard and connection_id to the data source. The description maps 'connections (data sources)' to connection_id and 'dashboard' to artifactId, providing just enough disambiguation. Since param names carry most of the meaning, a 3 is appropriate.

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

Purpose4/5

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

The description states a specific verb ('Attach'), a resource ('connections/data sources'), and a target ('a Duvo Pulse dashboard'), and adds the agent-relevant outcome ('so the agent can use its tools'). It is clear enough to distinguish from siblings like detachPulseDashboardConnection, though it doesn't name that sibling explicitly.

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

Usage Guidelines3/5

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

The description implies the usage context: attaching an existing connection to a dashboard, and it parenthetically adds the prerequisite 'requires edit access'. However, it does not state when to prefer this over listPulseDashboardConnections or createConnection, nor give any exclusions or alternatives.

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

attachRevisionIntegrationsAttach Revision IntegrationsAInspect

Attach one or more integrations to an agent revision. To pin specific connections after attachment, use pinRevisionIntegrationConnection. IMPORTANT for the case-queue-producer and case-queue-consumer integrations: attaching the integration alone is NOT enough — the slot points at no queue and will fail at runtime until you link at least one queue with replaceRevisionIntegrationQueues. After wiring up, call getRevisionCaseQueueSetup to confirm every case-queue slot has linked_queue_count > 0 before starting work.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID
integration_idsYesIntegration IDs (or custom integration IDs) to attach to the revision
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

A4.7/5.0
Behavior4/5

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

The description discloses a critical non-obvious behavior: attaching case-queue integrations alone leaves the slot pointing at no queue and will fail at runtime until queues are linked. It also recommends a verification step. While annotations already indicate this is a mutating operation (readOnlyHint=false), the description adds meaningful behavioral caveats beyond the structured annotations.

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

Conciseness5/5

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

Three sentences, front-loaded with the core action, then the alternative tool, then the important workflow caveat. Every sentence earns its place; no fluff or repetition of schema details.

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?

Given the tool's complexity and lack of an output schema, the description is remarkably complete: it states the action, routes to the correct sibling for pinning, warns about a runtime failure mode, and tells the agent how to verify success. An agent has enough context to invoke this correctly and know when additional steps are required.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics for integration_ids by singling out case-queue-producer and case-queue-consumer integrations and explaining their runtime requirements. This goes beyond the schema's generic 'Integration IDs...' description.

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 clearly states the verb and resource: 'Attach one or more integrations to an agent revision.' It also distinguishes itself from the sibling pinRevisionIntegrationConnection by explaining that pinning is a separate follow-up action. This is specific enough for an agent to know exactly what the tool does.

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

Usage Guidelines5/5

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

It explicitly says to use pinRevisionIntegrationConnection for pinning connections after attachment. It also gives a clear workflow for case-queue integrations: attach → link queues via replaceRevisionIntegrationQueues → verify with getRevisionCaseQueueSetup. This is explicit when-to-use and when-to-use-alternative guidance.

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

attachRevisionLoginAttach Revision LoginBInspect

Attach a login to a revision so the agent can use it during Runs spawned from that revision. Personal logins can only be attached by their owner; team-shared logins require builder permissions.

NameRequiredDescriptionDefault
agentIdYes
buildIdYes
exposedCredentialIdYes

TDQS

B3.2/5.0
Behavior3/5

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

It discloses permission requirements (owner vs builder) but does not mention idempotency, side effects on existing attachments, or what happens if the login is already attached. The description is partially transparent about behavior.

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

Conciseness5/5

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

The description is concise, two sentences long, and contains no redundant or extraneous information. It efficiently conveys the core purpose and a key constraint.

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

Completeness3/5

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

The description provides the primary purpose and permission context, but it does not mention the return value, potential errors, or behavior in edge cases. Given the lack of output schema and parameter descriptions, it is not fully complete from an agent's perspective.

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

Parameters1/5

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

The schema provides no descriptions, and the tool description does not clarify the meaning of parameters like agentId, buildId, or exposedCredentialId. Users cannot infer from the description how these map to the concept of 'attach a login to a revision'.

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 clearly states the action (attach), the resource (login), and the target (revision), and explains the purpose (for use during Runs). It effectively distinguishes this from similar tools by focusing on the specific action and its intent.

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

Usage Guidelines2/5

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

The description does not explicitly state when to use this tool versus alternatives like attachRevisionSecret or detachRevisionLogin. It provides permission constraints but lacks comparison or selection criteria for an agent.

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

attachRevisionSecretAttach Revision SecretAInspect

Attach an env-var secret to a revision so its keys are injected into Runs spawned from that revision. Personal secrets can only be attached by their owner; team-shared secrets require builder permissions.

NameRequiredDescriptionDefault
agentIdYes
buildIdYes
credentialIdYes

TDQS

A4/5.0
Behavior4/5

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

With annotations carrying only generic false hints, the description adds meaningful behavioral detail: the operational effect on Runs and the ownership/permission constraints. It does not contradict annotations and gives an agent a realistic expectation of side effects.

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

Conciseness5/5

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

Two front-loaded sentences: the first states the action and effect, the second adds permission constraints. No redundant or filler content.

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

Completeness3/5

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

The description covers purpose, effect, and permissions, which is adequate for a simple mutation tool. However, with no output schema, no parameter descriptions, and no annotation details, an agent is left to infer the meaning of the three UUID parameters, so the definition is not fully complete.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate for the undocumented agentId, buildId, and credentialId. It mentions 'secret' and 'revision' conceptually but never maps those concepts to the actual parameters or explains what each ID refers to.

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 uses a specific verb ('Attach'), names the resource ('env-var secret to a revision'), and states the expected effect ('keys are injected into Runs spawned from that revision'). This clearly differentiates it from siblings like attachRevisionIntegrations and detachRevisionSecret.

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 states clear context for when this operation applies—attaching a secret to a revision for injection into Runs. It adds permission conditions for personal vs team-shared secrets, though it does not explicitly name alternatives or when-not-to-use cases.

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

authorizeMcpOAuthAuthorize Mcp OAuthAInspect

Start an OAuth-based connection with a remote MCP server using Dynamic Client Registration. Returns an authorization URL the user must open in a browser; once they grant consent, Duvo creates the matching connection and redirects the browser to the optional returnUrl.

NameRequiredDescriptionDefault
nameYesHuman-readable name to display for the connection.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
return_urlNoWhere to send the user's browser after consent completes. Accepts an absolute URL on a domain Duvo allows, or a path relative to the Duvo frontend (e.g. `/integrations/slack`).
mcp_server_urlYesURL of the MCP server requiring OAuth.
oauth_client_idNoOAuth client ID of a client the user registered on the authorization server themselves (e.g. a NetSuite Integration record). Takes precedence over preregistered credentials and Dynamic Client Registration. Cannot be combined with custom_integration_id. On reconnect, omit to reuse the connection's stored credentials, or provide to replace (rotate) them.
integration_typeNoOptional catalog integration type (e.g. `netsuite`, `asana`). When it names a known MCP OAuth catalog integration and `mcp_server_url` matches that integration's registered server, the connection is treated as a catalog connection; otherwise it requires the custom MCP servers capability.
oauth_client_secretNoClient secret for `oauth_client_id`. Omit for public clients (PKCE-only).
custom_integration_idNoOptional ID of a custom integration this connection should be associated with.
reconnect_instance_idNoWhen set, the OAuth flow will update the existing connection in place rather than creating a new one.

TDQS

A3.8/5.0
Behavior4/5

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

The description adds meaningful behavioral context beyond the annotations: it reveals an interactive browser step, that the tool returns an authorization URL, that user consent is required, and that Duvo creates the connection afterward. These are important operational traits that annotations alone do not convey. It does not contradict the annotations.

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

Conciseness5/5

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

The description is a single, dense sentence that front-loads the purpose and then explains the full flow. Every phrase earns its place: the method (Dynamic Client Registration), the intermediate result (authorization URL), the required user action, and the final outcome (connection creation and redirect). No filler or redundancy.

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

Completeness4/5

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

Given the tool's complexity (9 parameters, no output schema), the description is largely complete: it explains the interactive nature, the side effect of creating a connection, and the returnUrl behavior. It does not cover failure scenarios or mention prerequisites like required capabilities, but the schema covers parameter-level details well enough.

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 individual parameters are already fully documented. The description adds some context by mentioning Dynamic Client Registration and the optional returnUrl behavior, but it does not substantially explain parameters beyond what the schema provides. Baseline 3 is appropriate.

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

Purpose4/5

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

The description states a specific verb and resource: 'Start an OAuth-based connection with a remote MCP server using Dynamic Client Registration.' It clearly explains the tool's core function and outcome (returns an authorization URL, creates a connection after consent). However, it does not explicitly distinguish itself from sibling tools like startNativeOAuth or checkMcpOAuth, so it stops short of a 5.

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

Usage Guidelines3/5

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

The usage context is reasonably implied: use this tool when you need to establish an OAuth connection to a remote MCP server. Yet the description never explicitly names alternatives, such as startNativeOAuth or probeMcpServer, or states when not to use this tool. This leaves the agent to infer routing from tool names rather than from explicit guidance.

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

batchAddClarityLandscapeNodePeopleBatch Add Clarity Landscape Node PeopleAInspect

Add one or more people to multiple Process Landscape nodes in a bounded batch. Email entries can create invitations; each node-person outcome reports success, conflict, or delivery failure.

NameRequiredDescriptionDefault
orgIdYes
peopleYes
nodeIdsYes

TDQS

A3.5/5.0
Behavior4/5

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

Annotations already declare non-readOnly, non-idempotent, non-destructive, openWorld. The description goes beyond them by disclosing a side effect not visible in the schema (email entries can create invitations) and the per-outcome result taxonomy (success, conflict, delivery failure). It still omits auth/permission requirements and partial-failure semantics.

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

Conciseness5/5

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

Two sentences, no filler, and the core action and batch scope are front-loaded before the side-effect/outcome detail. Every clause earns its place.

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

Completeness3/5

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

For a batch mutation with no output schema and no annotations covering safety beyond hints, the description gives the action, side effect, and outcome vocabulary, which is a reasonable core. It stops short of batch-size limits, permission requirements, and what happens when some node-person pairs fail, which matter for a 20x20-style bulk operation.

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

Parameters2/5

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

Schema description coverage is 0%, so the description carries the burden, yet it only hints at the meaning of the email field (invitations). orgId, nodeIds, and the required per-person fields name, processRole, and teamRole are never explained, leaving most parameters documented nowhere.

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

Purpose4/5

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

States a specific verb (Add), resource (people), and target (multiple Process Landscape nodes) with an explicit batch scope. It implicitly separates itself from the singular sibling addClarityLandscapeNodePerson by emphasizing 'one or more people to multiple nodes', but never names that sibling, so differentiation is left to inference.

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

Usage Guidelines3/5

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

The phrase 'bounded batch' implies this is the tool for multi-node/multi-person adds, which is usable context, but there is no explicit when-to-use/when-not-to-use guidance and no mention of the singular alternative addClarityLandscapeNodePerson. Usage is implied rather than stated.

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

buildClarityAutomationBuild Clarity AutomationAInspect

Hand an automation proposal for a v2 clarity process off to the workflow-builder pipeline. Builds from transformation_proposal_id when supplied, otherwise from the process's live proposal. The proposal id is the durable idempotency key, so retries return the same run and a different proposal starts a new run. Returns 202 while the LLM run completes asynchronously, or 409 when the resolved proposal is still being written.

NameRequiredDescriptionDefault
process_idYesThe clarity process id
transformation_proposal_idNoAutomation-proposal snapshot to build the automation from. Defaults to the process's live proposal.

TDQS

A3.5/5.0
Behavior1/5

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

The description claims the proposal id is a durable idempotency key and that retries return the same run, but annotations declare idempotentHint=false. This is a direct contradiction between the described behavior and the annotation metadata, which the scoring rules treat as a serious failure.

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

Conciseness5/5

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

The description is compact and well-structured: it states the action, explains the input-resolution rule, covers idempotency, and describes the two relevant HTTP statuses. Every sentence adds useful information without padding.

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

Completeness4/5

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

The description covers the key operational behaviors: input selection, idempotency, asynchronous completion, and conflict handling. It does not mention how to track the resulting run or what a successful response body contains, but for a fire-and-forget async build tool the provided context is largely sufficient.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3. The description adds meaningful semantics beyond the schema by explaining that transformation_proposal_id defaults to the process's live proposal and acts as an idempotency key, giving the agent a better understanding of how the parameter controls execution.

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

Purpose4/5

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

The description clearly states the tool's function: handing an automation proposal off to the workflow-builder pipeline and building an automation from a proposal. It is specific about the resource and action, though it does not explicitly differentiate itself from sibling tools like createAutomation or updateAutomation.

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?

The description provides clear context on how the tool selects its input: it uses transformation_proposal_id when supplied, otherwise the process's live proposal. It does not explicitly state when to use this tool versus alternative automation-creation tools, but the parameter-selection logic is clear.

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

bulkCreateTeamInvitesBulk Create Team InvitesAInspect

Invite several people to a team in one call, emailing each invitation immediately. Returns per-batch counts: succeeded were invited, skipped were already on the team, already had a pending invitation, or were a duplicate of an earlier entry in the same batch, failed could not be emailed (those invitations are rolled back). The accept link is always built from the server-configured app origin.

NameRequiredDescriptionDefault
membersYesPeople to invite, at most 50 per request. An email already on the team, or already holding a pending invitation, is skipped rather than failing the batch.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
frontendUrlNoDeprecated. Accepted for backward compatibility and IGNORED: the accept link is always built from the server-configured app origin, so a caller cannot point invitation emails at another host.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint false, idempotentHint false), the description discloses immediate emailing, per-batch outcome categories, rollback of failed invites, and the server-controlled accept-link origin. No contradiction with annotations.

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

Conciseness5/5

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

Three sentences with no filler: the main action is first, followed by the return semantics, then a clarifying note about the accept link. Every sentence earns its place.

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?

With no output schema, the description carries the burden of explaining return values; it defines succeeded/skipped/failed and rollback. Combined with the detailed team_id parameter schema, an agent has what it needs to invoke the tool correctly without guessing.

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

Parameters4/5

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

Schema coverage is 100%, so the baseline is 3, but the description adds genuine value by explaining member-level outcomes (succeeded/skipped/failed), duplicate handling within the same batch, and rollback semantics for failed emails, which the schema does not fully spell out.

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 action and resource: 'Invite several people to a team in one call, emailing each invitation immediately.' The bulk scope is explicit, which distinguishes it from single-invitation siblings such as createTeamInvite without needing to open the schema.

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?

Batch context is clear and the team_id parameter guidance is unusually specific (API keys pinned to one team should omit or pass the same team; OAuth callers should pass the target team). It stops short of explicitly naming an alternative for single invites or stating when not to use the tool, but the context is clear enough.

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

bulkGenerateClarityProcessSnapshotsBulk Generate Clarity Process SnapshotsAInspect

Start snapshot generation for many v2 clarity processes in the current team. Starts at most a share of the free sandbox capacity per call; the rest come back in deferred and should be sent again once some of the started runs finish. Processes that cannot start (already generating, no usable interviews, not found) come back in skipped with the reason.

NameRequiredDescriptionDefault
kindYesSnapshot kind to list
process_idsYesClarity v2 process ids to generate maps for
transformation_aggressivenessNoTransformation proposals only: the transformation appetite. `aggressive`, `conservative`, and `none` redesign around Duvo automation with decreasing freedom to change the process; `optimize` standardizes and streamlines the process while every step stays performed by people.aggressive

TDQS

A3.9/5.0
Behavior5/5

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

Annotations only cover the safety profile (not read-only, not idempotent, not destructive). The description goes well beyond that: it discloses a throughput constraint (at most a share of free sandbox capacity per call), partial-execution semantics with a `deferred` bucket to be retried, and an explicit `skipped` bucket with reasons. That is exactly the kind of capacity/rate-limit and failure-mode context annotations cannot express.

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

Conciseness4/5

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

Three tight sentences, front-loaded with what the tool does before moving to the deferred/skipped semantics. No filler; each sentence carries information about execution behavior. Slightly dense but well ordered.

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

Completeness4/5

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

With no output schema, the description helpfully explains the shape of the result (deferred vs skipped with reasons), which is what an agent needs to drive the retry loop. It stops short of quantifying the capacity share or saying how to detect that started runs have finished, so an agent must infer the polling step.

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% and all three parameters (including both enums) are documented in the schema, so the baseline of 3 applies. The description adds no syntax or format detail beyond the schema — it mentions processes generically but never explains `kind` or `transformation_aggressiveness`.

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

Purpose4/5

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

States a specific verb and resource ('Start snapshot generation for many v2 clarity processes') and the scope ('current team'). The word 'many'/bulk distinguishes it in spirit from the single-process sibling generateClarityProcessSnapshot, but the description never names that alternative, so differentiation is inferred rather than explicit.

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

Usage Guidelines3/5

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

It gives real operational guidance on the retry loop ('the rest come back in `deferred` and should be sent again once some of the started runs finish'), which is genuinely useful. However it never states when to use this bulk tool versus generateClarityProcessSnapshot for a single process, or any precondition about sandbox capacity being available.

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

bulkReprocessCasesBulk Reprocess CasesA
Destructive
Inspect

Re-process multiple cases on a chosen agent. Any active runs on the selected cases are interrupted first; the cases are then reset to pending and assigned to the chosen agent for the next dispatcher tick. The chosen agent must already be connected to the queue as a case-queue-consumer (with the trigger enabled or disabled) and not belong to a different automation than the queue.

NameRequiredDescriptionDefault
searchNoFree-text search selecting the cases when all_matching is true.
filtersNoFilters selecting the cases when all_matching is true.
agent_idNoThe agent that should run on the selected cases. Must be a consumer of this queue and not belong to a different automation.
case_idsNoExplicit case IDs to act on (1-100). Provide this or set all_matching.
queue_idYesThe queue's unique identifier
all_matchingNoWhen true, act on every case matching the provided filters/search instead of an explicit id list.

TDQS

A4.2/5.0
Behavior4/5

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

Adds real behavioral context beyond the annotations: active runs are interrupted first, cases are reset to pending, and dispatch happens on the next dispatcher tick. That tells the agent what is destroyed and when the effect materializes. It omits throughput/volume limits (e.g., how many cases the all_matching path can hit) and any confirmation or return information.

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

Conciseness5/5

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

Three tight sentences, front-loaded with the core action and sequencing, then prerequisites. No filler or restated name/title content.

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

Completeness4/5

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

Covers the operation, its side effects, and agent preconditions for a 6-parameter tool with nested filters and no output schema. It could say what the call returns (e.g., which/how many cases were queued) since no output schema exists to carry that, but nothing critical for correct invocation is missing.

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 schema already documents queue_id, agent_id, case_ids, all_matching, search, and filters. The description restates the agent_id constraint (queue consumer, same automation) but adds no syntax or format detail beyond the schema, making the baseline 3 appropriate.

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?

States a specific verb+resource+scope: re-processing multiple cases on a chosen agent, with the exact mechanism (interrupt active runs, reset to pending, reassign). This distinguishes it from neighbors like bulkUpdateCaseStatus, bulkUpdateCasePriority, and startRun, which mutate status or launch a run without touching the agent assignment.

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?

Gives concrete preconditions for use: the agent must already be a case-queue-consumer of the queue (trigger enabled or disabled) and must not belong to a different automation than the queue. It does not explicitly contrast with alternatives such as startRun or bulkUpdateCaseStatus, so it stops short of a full when/when-not routing statement.

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

bulkUpdateCasePriorityBulk Update Case PriorityA
Destructive
Inspect

Set the priority of multiple cases. Priority only affects the order pending cases are picked up in: due postponed cases are handled first, then higher priority. It never interrupts runs or changes case status. Set none to clear priority back to the default.

NameRequiredDescriptionDefault
searchNoFree-text search selecting the cases when all_matching is true.
filtersNoFilters selecting the cases when all_matching is true.
case_idsNoExplicit case IDs to act on (1-100). Provide this or set all_matching.
priorityYesTarget priority for each case. `medium`/`high` raise it above the default; `none` clears it.
queue_idYesThe queue's unique identifier
all_matchingNoWhen true, act on every case matching the provided filters/search instead of an explicit id list.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare the write/destructive profile, and the description adds genuinely new semantics: priority ordering (due postponed cases first, then higher priority), that it never interrupts runs or changes status, and that `none` resets to default. It does not cover auth needs, bulk size limits, or partial-failure behavior, so it falls short of 5.

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

Conciseness5/5

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

Three tight sentences with no filler; the core action is front-loaded and the qualifiers (ordering semantics, non-disruption, reset) each earn their place.

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

Completeness4/5

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

For a bulk mutation tool with no output schema, the description covers the effect and its boundaries well. Minor gaps remain around bulk limits and per-case failure handling, but the essential behavior is conveyed.

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 all six parameters are documented in the schema; the description re-explains the `priority` enum values and the `none` reset, which adds some but not substantial meaning beyond the schema. Baseline 3 applies.

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?

States a specific verb and resource ('Set the priority of multiple cases') with the 'bulk/multiple' scope explicit. It distinguishes itself from the nearest sibling, bulkUpdateCaseStatus, by stating it 'never ... changes case status', so an agent can separate the two without reading schemas.

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?

Explains the operational context (priority governs pickup order for pending cases) and implicitly routes away from status mutation, giving clear when-to-use context. It stops short of an explicit 'use X instead when Y' exclusion statement, so it is not a full 5.

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

bulkUpdateCaseStatusBulk Update Case StatusA
Destructive
Inspect

Update the status of multiple cases to pending, completed, failed, or canceled. Interrupts any active runs and releases their case ownership, but never cancels their human-in-the-loop state — pending requests and open approval batches stay answerable/resolvable from the run view. Settling a case archives the pending requests on every run attached to it, both the runs this call interrupted and any that were already terminal, so they leave the activity inbox instead of outliving the case there. Resetting to pending archives nothing and re-dispatches cases to the queue's trigger consumer.

NameRequiredDescriptionDefault
searchNoFree-text search selecting the cases when all_matching is true.
statusYesTarget status for each case. `completed`, `failed`, and `canceled` are terminal — `canceled` records a deliberate human stop, distinct from a system `failed`. `pending` resets the case (the queue's trigger consumer, if any, will re-claim it). `success` is not settable: it means an evaluation passed.
filtersNoFilters selecting the cases when all_matching is true.
case_idsNoExplicit case IDs to act on (1-100). Provide this or set all_matching.
queue_idYesThe queue's unique identifier
all_matchingNoWhen true, act on every case matching the provided filters/search instead of an explicit id list.

TDQS

A4.1/5.0
Behavior5/5

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

Beyond the annotations (destructiveHint=true, idempotentHint=false), the description discloses concrete side effects an agent must know before calling: it interrupts active runs and releases case ownership, deliberately preserves human-in-the-loop state so pending requests remain answerable, archives pending requests across all attached runs when settling, and archives nothing when resetting to pending. This is exactly the kind of irreversible-consequence detail a destructive bulk tool needs.

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

Conciseness4/5

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

The core action is front-loaded in the first sentence, and the subsequent sentences each cover a distinct consequence (run interruption, human-in-the-loop preservation, archival on settle vs reset). It is dense and longer than average, but every clause carries operational weight for a destructive bulk mutation.

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

Completeness4/5

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

With no output schema and a destructive bulk operation, the description covers the critical blast-radius details (run interruption, ownership release, archival scope, re-dispatch on reset). It omits only secondary concerns such as permission requirements and partial-failure behavior, which keeps it short of a 5.

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 schema already documents all six parameters including the status enum and its reset semantics. The description's mention of the four settable statuses and the reset behavior largely restates what the schema already carries, so it adds little parameter-level meaning beyond the baseline.

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 states a specific verb+resource+scope: 'Update the status of multiple cases to pending, completed, failed, or canceled.' The bulk scope and the enumeration of target statuses let an agent distinguish it from single-case updateCase and from bulkUpdateCasePriority or bulkReprocessCases without opening a schema.

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

Usage Guidelines3/5

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

Usage is implied by 'multiple cases' (use when acting on many at once, rather than the single-case sibling), but the description never explicitly says when to prefer this over updateCase or the other bulk siblings. It gives no exclusions or prerequisites, so routing relies on inference.

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

cancelBuilderRunCancel Builder RunB
Destructive
Inspect

Cancel a running builder run and pause its sandbox

NameRequiredDescriptionDefault
statusYesCancel an in-progress generation; review-pending changes must be declined instead.
builder_run_idYesThe builder run identifier.

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare destructiveHint=true and idempotentHint=false, so safety is largely covered. The description adds one genuinely new behavioral detail beyond the annotations — that the sandbox is paused as a side effect — but says nothing about reversibility, resume path, or downstream effects on in-progress work.

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

Conciseness5/5

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

A single front-loaded sentence with zero filler. The primary action and its side effect are both stated immediately with no redundancy.

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

Completeness4/5

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

Given the rich annotations (destructive, non-idempotent) and the fully documented schema that carries the important decline-instead nuance, the description is nearly complete. A brief note that cancellation is not reversible/undoable would close the remaining gap.

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 coverage is 100% and both parameters are described in the schema, including the const status value and the uuid format. The description adds no parameter-level meaning beyond the schema, so the baseline 3 applies.

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

Purpose4/5

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

"Cancel a running builder run and pause its sandbox" states a specific verb (cancel), a specific resource (builder run), and even a secondary effect (sandbox pause). It clearly distinguishes from the sibling getBuilderRun and resumeBuilderRun, though it doesn't name those alternatives explicitly.

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

Usage Guidelines2/5

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

The description offers no when-to-use guidance, prerequisites, or alternatives. The useful scoping note ("review-pending changes must be declined instead") lives in the status schema property, not the description, so the description itself leaves routing entirely to inference.

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

checkMcpOAuthCheck Mcp OAuthBInspect

Probe an MCP server URL to discover whether it supports OAuth Dynamic Client Registration. Returns the authorization endpoint and required scopes when supported. Useful as a precursor to /v2/teams/:team_id/connections/oauth/mcp/start or /v2/teams/:team_id/connections. Performs no writes.

NameRequiredDescriptionDefault
mcp_server_urlYesURL of the MCP server to probe for OAuth support.

TDQS

B3.3/5.0
Behavior1/5

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

The description states 'Performs no writes,' which directly contradicts the readOnlyHint=false annotation. This is a serious inconsistency: the annotation implies the tool may modify state while the description asserts it never writes. Because the description contradicts structured metadata, it earns the minimum score and should be flagged.

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

Conciseness5/5

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

The description is three sentences with no filler: it states the action, the return value, the intended precursor role, and the non-writing behavior. Key information is front-loaded before secondary details.

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

Completeness3/5

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

For a low-complexity single-parameter tool with no output schema, the description covers the main purpose and partially describes returns ('authorization endpoint and required scopes when supported'). However, it does not explain what happens when OAuth Dynamic Client Registration is not supported, and the annotation contradiction undermines the reliability of the tool's behavioral contract.

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?

The single parameter mcp_server_url has 100% schema description coverage, so the schema already explains it as 'URL of the MCP server to probe for OAuth support.' The description adds no extra semantic detail beyond what the schema provides, so the baseline score of 3 is appropriate.

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

Purpose4/5

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

The description clearly identifies a specific action (probe an MCP server URL), a resource (MCP server), and a concrete outcome (discover OAuth Dynamic Client Registration support, return authorization endpoint and scopes). It does not explicitly differentiate itself from the similar sibling 'probeMcpServer', so it falls short of a 5.

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?

The description gives clear usage context by naming the endpoints this tool is a precursor to ('/v2/teams/:team_id/connections/oauth/mcp/start' and '/v2/teams/:team_id/connections'). However, it does not mention alternatives like probeMcpServer or state when not to use it, so no exclusions are provided.

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

completeClarityArtifactImportComplete Clarity Artifact ImportAInspect

Complete a Miro artifact import after uploading to the signed URL. The uploaded bytes are validated before the import becomes a usable Clarity capture.

NameRequiredDescriptionDefault
file_nameYesName of the Miro export file. Supported extensions: .svg, .xml, .png, .jpg, .jpeg
capture_idYesThe pending capture id returned by the upload-url endpoint
process_idYesThe clarity process id
content_typeYesMIME type of the uploaded Miro export file

TDQS

A3.7/5.0
Behavior3/5

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

Annotations already signal this is a non-read-only, non-idempotent operation. The description adds a useful behavioral detail: uploaded bytes are validated before the import becomes a usable capture. It does not disclose failure behavior or what happens if validation fails, but it provides more context than the annotations alone.

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

Conciseness5/5

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

Two short sentences with no filler or repetition. The core action is front-loaded, and the validation step is presented as a meaningful second sentence.

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

Completeness3/5

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

The description covers the main flow and outcome, and the schema fully documents parameters, but it omits response semantics and failure behavior for validation. For a non-idempotent state-changing tool without an output schema, this is a minimal but slightly incomplete definition.

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?

The input schema already documents all four parameters with descriptions and constraints at 100% coverage. The description adds general workflow context but no parameter-specific meaning beyond what the schema provides, so the baseline of 3 is appropriate.

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

Purpose4/5

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

The description identifies a specific verb ('complete') and resource ('Miro artifact import'), and adds process context about uploading to a signed URL and becoming a usable Clarity capture. It is distinguishable from sibling upload-completion tools by 'artifact import,' though it does not explicitly contrast them.

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?

The description clearly states the temporal context: call this tool after uploading to the signed URL. It does not mention alternatives or exclusions, but the sequencing is explicit enough for an agent to understand when in the workflow this belongs.

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

completeClarityDocumentUploadComplete Clarity Document UploadAInspect

Complete a document capture after uploading to GCS via signed URL

NameRequiredDescriptionDefault
idYesThe clarity process ID
fileNameYesName of the uploaded document file
captureIdYesThe capture ID

TDQS

A3.6/5.0
Behavior3/5

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

Annotations already indicate this is a non-read-only, non-idempotent, non-destructive mutation, so there is no contradiction. The description adds the useful precondition that the upload must already have happened, but it does not disclose what state changes occur, whether repeated calls fail, or what downstream effects completion triggers.

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

Conciseness5/5

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

A single sentence with the action front-loaded and the key prerequisite included. There is no redundant restatement of the schema or filler.

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

Completeness4/5

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

For a simple three-parameter completion step with fully documented parameters, the description gives the essential workflow context: this call finalizes a document capture after the GCS signed-URL upload. It does not describe return values or detailed side effects, but those are not necessary for a basic completion call given the schema and annotations.

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?

The schema covers 100% of parameters with meaningful descriptions: id, captureId, and fileName are all explained. The description adds no parameter-level details beyond the schema, so it meets the baseline for high schema coverage without needing to compensate.

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

Purpose4/5

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

The description identifies a concrete action ('Complete a document capture') and a specific workflow step ('after uploading to GCS via signed URL'), which separates it from upload-creation tools and from image/video completion tools. It does not explicitly contrast with completeClarityOrganizationDocumentUpload or completeClarityTeamDocumentUpload, so some sibling differentiation relies on the tool name.

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

Usage Guidelines3/5

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

The phrase 'after uploading to GCS via signed URL' provides a clear temporal condition and tells the agent when in the workflow this tool should be called. However, it does not name alternative completion tools or state when to prefer the organization/team/artifact variants, leaving routing to inference.

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

completeClarityImageUploadComplete Clarity Image UploadAInspect

Complete an image capture after uploading it to GCS via a signed URL

NameRequiredDescriptionDefault
idYesThe clarity process ID
fileNameYesName of the uploaded image file
captureIdYesThe capture ID

TDQS

A3.9/5.0
Behavior3/5

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

Annotations already establish this is a non-read-only, non-idempotent, non-destructive write. The description adds one genuinely useful behavioral trait beyond that: the hard prerequisite that the GCS upload via signed URL must happen first. However, it does not disclose what 'complete' does to the capture's state, what happens if invoked before the upload, or the consequences of calling twice (relevant given idempotentHint=false).

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

Conciseness5/5

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

A single 15-word sentence that front-loads the verb and object, then appends the only necessary context (the GCS signed-URL prerequisite). There is no redundancy with the title, no fluff, and every word contributes.

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

Completeness3/5

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

For a tool with 3 required params, no output schema, and no nested objects, the description covers the basic what and when. But it leaves gaps: it never references the createClarityImageUploadUrl pairing that produces the signed URL, it does not clarify how the three IDs relate to the upload flow, and with no output schema it says nothing about what a successful completion returns or triggers.

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% — each of the three parameters (id, captureId, fileName) has a description in the schema. Per the baseline for high coverage, the description need not repeat param details, and it doesn't. The description adds no extra meaning about which ID maps to which part of the flow, but the schema already carries the documentation burden adequately.

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 uses a specific verb ('Complete') with a specific resource ('an image capture') and adds the scoping context ('after uploading it to GCS via a signed URL'). This cleanly distinguishes it from the sibling family: completeClarityVideoUpload, completeClarityDocumentUpload, and the other complete* tools differ by resource type (image vs video vs document/artifact).

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?

The phrase 'after uploading it to GCS via a signed URL' gives clear sequencing context: this is the second step of a two-phase flow, implicitly paired with a URL-creating tool like createClarityImageUploadUrl. It does not explicitly name alternatives or state exclusions (e.g., 'use completeClarityVideoUpload for videos'), so it stops short of full when-not-to-use guidance.

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

completeClarityOrganizationDocumentUploadComplete Clarity Organization Document UploadAInspect

Complete an organization document capture after uploading to GCS; extracts text and stores it as a transcript so it feeds Process Landscape generation

NameRequiredDescriptionDefault
orgIdYes
fileNameYesName of the uploaded document file
interviewIdYesThe organization interview ID

TDQS

A4/5.0
Behavior4/5

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

Annotations already mark it non-read-only and non-destructive; the description adds useful behavioral context by stating it extracts text, stores a transcript, and feeds Process Landscape generation. It does not mention idempotency consequences, but idempotentHint=false already signals that risk.

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

Conciseness5/5

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

A single, front-loaded sentence states the action, the precondition, the processing behavior, and the downstream consumer with no filler. Every clause contributes to helping the agent decide and invoke the tool.

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

Completeness4/5

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

For a 3-parameter, multi-step completion operation with no output schema, the description covers the main workflow and downstream outcome, which is enough for a capable agent. The main gap is that it does not describe the return value or what happens on failure, but these are minor against the clear purpose and schema coverage.

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?

The schema describes interviewId and fileName but leaves orgId undocumented at 67% coverage. The description does not add parameter-specific meaning or explain how orgId/interviewId/fileName relate to the capture, so it neither compensates for the missing orgId description nor enriches the covered parameters.

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 uses a specific verb ('complete'), identifies the resource ('organization document capture'), and defines what completion entails: text extraction and transcript storage for Process Landscape generation. This distinguishes it from sibling upload-completion tools like completeClarityTeamDocumentUpload or completeClarityImageUpload.

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

Usage Guidelines3/5

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

It states a clear precondition ('after uploading to GCS') and implies the organization-document workflow, but it does not name alternatives or say when not to use it. An agent must infer that this is the org-specific counterpart to completeClarityDocumentUpload rather than being told.

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

completeClarityTeamDocumentUploadComplete Clarity Team Document UploadAInspect

Complete a team document capture after uploading to GCS; extracts text and stores it as a transcript so it feeds Process Landscape generation

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
fileNameYesName of the uploaded document file
interviewIdYesThe team interview ID

TDQS

A4.2/5.0
Behavior4/5

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

The description discloses the key state-changing behavior beyond the annotations: it 'extracts text and stores it as a transcript'. This aligns with readOnlyHint=false and destructiveHint=false, and adds useful context about what happens when the tool is invoked. It does not discuss idempotency or failure modes, but the core behavioral trait is transparent.

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

Conciseness5/5

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

The description is a single sentence that front-loads the action and context, then states the purpose. Every clause earns its place: the GCS precondition, the extraction/storage behavior, and the downstream use. There is no extraneous information.

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

Completeness4/5

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

For a tool with no output schema and three well-documented parameters, the description gives the essential operational context: when to call it, what it does, and why it matters. It could mention return behavior or error conditions if the GCS upload hasn't happened, but those are not critical for basic selection and invocation.

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 input schema already documents interviewId, fileName, and team_id thoroughly. The tool description adds no additional parameter-specific meaning, which is acceptable at the baseline given the schema's strong coverage.

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 names a specific verb ('Complete'), a specific resource ('team document capture'), and the concrete outcome ('extracts text and stores it as a transcript'). The phrase 'after uploading to GCS' clearly situates it in a two-step upload pipeline, and 'team' distinguishes it from sibling tools like completeClarityDocumentUpload and completeClarityOrganizationDocumentUpload.

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?

The description gives a clear sequential context: use this after the file has been uploaded to GCS. It also signals downstream relevance by noting the transcript 'feeds Process Landscape generation'. It does not explicitly enumerate when-not-to-use or name alternative sibling tools, but the team-specific wording makes the intended context clear.

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

completeClarityVideoUploadComplete Clarity Video UploadAInspect

Complete a video capture after uploading to GCS via signed URL

NameRequiredDescriptionDefault
idYesThe clarity process ID
fileNameYesName of the uploaded video file
captureIdYesThe capture ID

TDQS

A4/5.0
Behavior3/5

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

Annotations already signal that this is a non-read-only, non-idempotent mutation, so the description does not need to repeat those hints. It adds the useful sequencing context that the upload must already have happened, but it does not disclose what 'complete' does to the capture (e.g., status transition, validation, irreversibility).

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

Conciseness5/5

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

The description is a single, front-loaded sentence with no filler. It leads with the action and resource, then adds the essential precondition, making it efficient for an agent to parse.

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

Completeness4/5

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

For a three-parameter tool with no output schema and no nested objects, the description plus schema is adequate to invoke the tool: it names the action, the resource, and the required precondition. It could be more explicit about what completing the upload entails or that it pairs with createClarityVideoUploadUrl, but nothing essential is missing for correct invocation.

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?

The input schema already documents all three parameters with clear descriptions (clarity process ID, capture ID, uploaded file name) at 100% coverage. The description adds no parameter-specific semantics beyond tying fileName to the GCS upload flow, so the baseline 3 is appropriate.

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 states a specific action ('Complete a video capture') and the resource ('video capture'), with an explicit precondition ('after uploading to GCS via signed URL'). The word 'video' plus the completion-vs-creation verb clearly sets it apart from sibling tools like createClarityVideoUploadUrl and the other complete* upload variants.

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 clearly indicates the triggering condition: the tool should be called only after the video file has been uploaded to GCS via a signed URL. It does not explicitly name alternative tools or list when-not-to-use scenarios, but the context is sufficient for basic selection.

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

consumeAgentSuggestionConsume Agent SuggestionB
Destructive
Inspect

Apply a suggestion: stage its change into the Agent's draft revision, then auto-clear any pending suggestions it makes moot.

NameRequiredDescriptionDefault
idYesThe suggestion's unique identifier
revision_idNo
create_new_draftNo
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

B3.2/5.0
Behavior4/5

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

Annotations declare destructiveHint=true and idempotentHint=false, but the description adds two traits those hints do not convey: the change is staged into a *draft* revision (not applied live), and consuming a suggestion auto-clears other pending suggestions made moot. That side effect is exactly the kind of non-obvious behavior an agent needs to know before calling.

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

Conciseness4/5

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

A single tight sentence that front-loads the core action and then the side effect. No wasted words, though the placement of the auto-clear behavior at the end slightly buries a consequential detail.

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

Completeness3/5

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

For a destructive, non-idempotent mutation with no output schema, the description nails the mechanism and side effect but leaves two of four parameters unexplained and offers no routing to sibling tools. It is adequate for the happy path but incomplete for correct invocation in edge cases.

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

Parameters2/5

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

Schema coverage is only 50% — id and selected_automation_revision_id are documented, but revision_id and create_new_draft are undocumented in both schema and description. The description says nothing about any parameter, so it fails to compensate for the gap; an agent cannot tell what revision_id or create_new_draft do.

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

Purpose4/5

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

The description gives a specific verb+resource ('Apply a suggestion') and explains the mechanism (stage its change into the Agent's draft revision). It distinguishes itself implicitly from rejectAgentSuggestion and getAgentSuggestion, though it never names those siblings explicitly, so it stops short of a 5.

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

Usage Guidelines2/5

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

There is no when-to-use guidance, no prerequisites, and no mention of the obvious alternatives (rejectAgentSuggestion, getAgentSuggestion, listAgentSuggestions). The agent must infer the invocation context from the name alone.

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

createAgentCreate AgentAInspect

Create a new agent. Optionally include a build configuration to create the first build in the same request. On a team that versions its automations, an agent created inside an automation joins that automation's draft revision: its first build is a draft and goes live when the draft is made active.

NameRequiredDescriptionDefault
nameYesHuman-readable agent name
typeNoFlavour of the step to create. Fixed at creation — it selects the config family every build of this step must use, and the two cannot be mixed.agent
buildNoOptional inline build. When present, a first build is created alongside the agent. Only valid for an agent step.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
thread_idNoExisting thread ID to associate with the agent
automation_idNoAutomation this agent belongs to. If omitted on a team using the automations model, a new automation named after the agent is created automatically.
source_build_idNoBuild ID whose case-queue-consumer setup should be copied to the new agent. When `automation_id` is omitted, the new agent also joins the automation of the agent this build belongs to.

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare write, non-idempotent, non-destructive, so the bar is lower. The description still adds real value beyond them: the created agent's first build is a draft in the automation's draft revision and only goes live when that draft is made active — a non-obvious side effect an agent would otherwise miss. It stops short of stating return contents or auth requirements (team pinning lives only in the schema).

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

Conciseness5/5

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

Three sentences, front-loaded with the action, then the optionality, then the non-obvious release semantics. No filler and no repetition of schema content.

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

Completeness4/5

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

For a seven-parameter, deeply nested creation tool with rich schema coverage and safety annotations already present, the description covers the essential behavioral nuance. The only gap is that no output schema exists and the description never says what a successful call returns (presumably the new agent with its ID).

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 all seven parameters, including nested build/config fields, are already documented in the schema. The description only abstracts the build parameter's optionality and doesn't add format or constraint details beyond it — baseline 3 applies.

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?

"Create a new agent" is a specific verb+resource, and the second sentence scopes the optional build creation. An agent can distinguish this from updateAgent, duplicateAgent, and createRevision without opening the schema.

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

Usage Guidelines3/5

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

It conveys when the inline build path applies ("create the first build in the same request") and the automation-draft context, which implies usage. But it names no alternative (e.g. createRevision for later builds, or that code steps must use a different endpoint — that exclusion lives only in the schema), and gives no explicit when-not guidance.

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

createAgentCaseTriggerCreate Agent Case TriggerAInspect

Create a case trigger for an agent. An agent may have at most one case trigger; this returns 409 if one already exists.

NameRequiredDescriptionDefault
enabledYesWhether the trigger is active. Disabled triggers do not dispatch runs.
agent_idYesThe agent's unique identifier
concurrencyNoConcurrency cap for the target queue. The cap is queue-wide, so this affects every Agent working the queue, not just this trigger. Only 1 (run cases one at a time) or null (reset the whole queue's cap to the platform default) can be set here; higher caps are configured per-queue via PATCH /v2/admin/case-queues/{queueId}/concurrency. Omit to leave the queue's current cap unchanged.
case_queue_idYesQueue whose new cases should trigger this agent

TDQS

A4/5.0
Behavior4/5

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

Annotations already indicate this is a write operation (readOnlyHint=false). The description adds valuable behavioral context beyond that: the at-most-one invariant and the specific 409 failure mode when a trigger already exists. It does not detail success behavior or side effects, but the conflict behavior is a strong disclosure.

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

Conciseness5/5

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

Two sentences, no filler. The primary action is front-loaded, and the important uniqueness/conflict constraint follows immediately. Every sentence adds useful information.

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

Completeness4/5

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

The schema comprehensively documents all four parameters, and the description supplies the key behavioral constraint for a create operation. The main gap is that it does not describe the successful response shape or explicitly guide the agent toward update/upsert alternatives when a trigger already exists, but these are minor for this tool.

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?

Input schema coverage is 100%, so the description does not need to restate parameter meanings. The description adds no parameter-specific semantics beyond what the schema already provides; it only describes a trigger-level constraint.

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 states a specific action and resource: 'Create a case trigger for an agent.' It clearly differs from sibling tools by specifying 'case trigger' rather than, say, a Slack trigger, and it adds the meaningful uniqueness constraint that an agent can have at most one.

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

Usage Guidelines3/5

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

The description implies this tool is for creating a new case trigger and that an existing trigger will cause a 409. However, it does not explicitly mention alternatives such as updateAgentCaseTrigger or upsertAgentTrigger, nor does it say when to prefer one over the others.

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

createAgentFolderCreate Agent FolderCInspect

Create a new agent folder.

NameRequiredDescriptionDefault
nameYesHuman-readable folder name
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
parent_folder_idNoParent folder ID for nested folders. Omit or null to create at the root level.

TDQS

C2.9/5.0
Behavior2/5

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

Annotations provide readOnlyHint=false, destructiveHint=false, and idempotentHint=false, but the description adds no behavioral context beyond the creation act itself. It does not mention side effects, return values, uniqueness constraints, or how the folder relates to agents. No contradiction with annotations.

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

Conciseness4/5

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

The description is a single front-loaded sentence with no filler, which is appropriate for a simple create operation. However, it is minimal enough that it essentially restates the title, so it does not quite reach the highest tier.

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

Completeness3/5

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

The definition is largely sufficient given the fully documented schema and simple semantics. However, there is no output schema, and the description does not indicate what a successful creation returns or how the new folder is subsequently used, leaving some ambiguity for an agent.

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 schema already documents all three parameters, including detailed team_id and parent_folder_id semantics. The description itself adds no parameter-level detail, so the baseline 3 applies.

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

Purpose4/5

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

The description states a specific verb and resource: 'Create a new agent folder.' This is unambiguous and clearly distinct from siblings like createAgent or createClarityFolder by resource type, though it does not explicitly name those alternatives.

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

Usage Guidelines2/5

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

No guidance is given about when to use this tool versus related tools such as listAgentFolders, updateAgentFolder, deleteAgentFolder, or moveAgentsToFolder. There are no usage conditions, exclusions, or alternative routing.

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

createAgentSlackTriggerCreate Slack Channel TriggerAInspect

Create a Slack channel trigger on an agent (Agent in the Duvo UI): the agent starts a Run whenever a matching message is posted in the channel. An agent can carry one trigger per channel, so call this once per channel. The Slack workspace must be installed for the team AND bound to the agent's live build first (see the Slack bound-workspaces endpoint) — otherwise this returns 400.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier
channel_idYesSlack channel ID to watch, e.g. `C0123ABCD`.
is_privateNoWhether the channel is private. Defaults to false. Private channels require the Duvo Slack app to be invited to the channel.
match_ruleYesWhich channel messages fire the trigger: `{"kind":"all"}` for every message, or `{"kind":"contains","values":["invoice"]}` to match keywords.
channel_nameYesSlack channel name shown in Duvo, without the leading `#`, e.g. `support-inbox`.
trigger_typeYesTrigger type. Only `slack_channel_message` (a message posted in a Slack channel) is supported here.
slack_team_idNoSlack workspace (team) ID the channel belongs to, e.g. `T0123ABCD`. Defaults to the team's default installed workspace. Discover the workspaces an agent can use with the bound-workspaces endpoint.
integration_instance_idNoSpecific bound Slack connection to run the trigger off. Omit to use your own connection, or pass one returned by the bound-workspaces endpoint.

TDQS

A4.5/5.0
Behavior5/5

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

Annotations only convey read/write/idempotency/destructiveness flags. The description goes beyond them by explaining the trigger's side effect (a Run starts on matching messages), the one-trigger-per-channel limit, the binding prerequisite, and the 400 failure mode. This is substantial extra behavioral context.

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

Conciseness5/5

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

Three sentences carry all operative information with no filler: purpose/behavior, cardinality constraint, and prerequisite/failure. The most important scoping guidance is front-loaded.

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 an 8-parameter create operation with no output schema, the description covers what happens on success, the per-channel limitation, prerequisite setup, and the error condition, while the schema documents every parameter. There are no invocation requirements left unaddressed.

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 coverage is 100%, with each of the 8 parameters already described by name, format, defaults, and examples. The description reinforces the general matching and per-channel concepts but adds no parameter-specific semantics beyond the schema, so the baseline 3 is appropriate.

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 — 'Create a Slack channel trigger on an agent' — and then defines the tool's effect as starting a Run when a matching message is posted. Naming 'Slack channel trigger' distinguishes it from sibling case-trigger tools such as createAgentCaseTrigger.

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 operational conditions: call once per channel, and only after the Slack workspace is installed and bound to the agent's live build, with a 400 failure otherwise. It doesn't explicitly contrast with alternatives like upsertAgentTrigger or updateSlackTrigger, so it stops short of full routing guidance.

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

createAutomationCreate AutomationAInspect

Create a new automation. Its first agent is created alongside it so the caller lands on something editable; first_agent seeds that agent's name, configuration, and connections instead of the defaults. On a team on revision semantics the automation holds a single draft revision and no live revision, with the agent's first build bound into that draft, and the first activation makes the draft revision 1; on any other team the automation is a bare container and the build stands on its own.

NameRequiredDescriptionDefault
nameYesHuman-readable automation name.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
first_agentNoSeeds the automation's first agent, for example from an agent template. Anything left out takes the platform default.

TDQS

A3.6/5.0
Behavior4/5

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

Annotations already declare this is a non-destructive, non-idempotent write. The description adds substantial non-obvious behavior: an agent is created alongside the automation, `first_agent` seeds that agent, and revision semantics vary by team type, including draft-creation and activation behavior. It does not cover permissions, error cases, or return values.

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

Conciseness4/5

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

Three sentences, front-loaded with the core action and its main side effect. The revision-semantics sentence is long but earns its place by explaining a non-obvious branching behavior; no obvious filler is present.

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

Completeness3/5

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

The description does well on creation semantics and revision behavior for a complex nested tool, and the rich schema covers parameters. However, with no output schema, it says nothing about what the caller receives back after creation, nor about permissions or failure modes — a meaningful gap for a create endpoint.

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%, and the schema already documents `name`, `team_id`, and the deep `first_agent` structure. The description reinforces that `first_agent` seeds name, configuration, and connections instead of defaults, but adds only marginal meaning beyond the schema.

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

Purpose4/5

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

The description states a specific verb and resource: 'Create a new automation.' It adds that a first agent is created alongside it, which distinguishes the operation from a bare agent-creation call, though it does not explicitly name sibling tools like createAgent or duplicateAutomation.

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

Usage Guidelines3/5

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

Usage is implied by the purpose — starting an automation with an immediately editable first agent — but the description gives no explicit 'use this when' or 'use X instead' guidance. It also omits any mention of alternatives such as createAgent, duplicateAutomation, or buildClarityAutomation.

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

createCaseAttachmentUploadUrlCreate Case Attachment Upload UrlAInspect

Issue a signed URL for uploading a file to a case. The client must PUT the bytes to the returned URL with the returned Content-Type, then call the finalize endpoint so the attachment becomes visible on the case.

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier
filenameYes
queue_idYesThe queue's unique identifier
mime_typeYes
size_bytesYes

TDQS

A4/5.0
Behavior4/5

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

Goes meaningfully beyond the sparse annotations (all false hints) by disclosing that the tool issues a signed URL and that the attachment does not become visible until the finalize endpoint is called — a genuinely non-obvious two-phase behavioral trait. It also specifies the PUT-with-Content-Type requirement, which an agent could not infer from the schema. Signed-URL expiry and authorization needs are not mentioned, but the core behavioral disclosure is strong.

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

Conciseness5/5

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

Two sentences, roughly 50 words, with the core purpose front-loaded in the first sentence and the essential follow-up protocol in the second. Every clause earns its place; there is no filler or restatement of the title.

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

Completeness4/5

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

For a moderate-complexity tool with no output schema and minimal annotations, the description conveys the critical facts: what is returned (signed URL and Content-Type), the exact PUT protocol, and the dependency on the finalize endpoint. Minor omissions — signed-URL expiry, explicit size-limit emphasis, and failure behavior — leave some room, but the core flow is fully actionable.

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 only 40% (case_id and queue_id), so the description must partially compensate for filename, mime_type, and size_bytes. It adds real meaning by tying mime_type to the 'returned Content-Type' and framing the file fields as the payload to PUT, but it does not individually explain their constraints or semantics, leaving the 50MB size ceiling and length limits solely to the schema.

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

Purpose4/5

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

States a specific verb and resource — 'Issue a signed URL for uploading a file to a case' — which is unambiguous and anchored to the case domain, distinguishing it from generic upload-URL siblings like createFileUploadUrl. The finalize-step mention further scopes its role. It does not explicitly name a sibling for disambiguation, but the case-specific framing is sufficient.

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?

Provides explicit protocol guidance: the client 'must PUT the bytes to the returned URL with the returned Content-Type, then call the finalize endpoint,' which tells an agent exactly how to consume the result and that a mandatory follow-up call exists. It does not state exclusions or route among alternatives such as createFileUploadUrl, but the intended usage context is clearly conveyed.

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

createCaseQueueEvalRubricCreate Case Queue Eval RubricAInspect

Add one case-level evaluation rubric to a queue's current rubric set. Case-level rubrics judge the whole case (across every Run that touched it) as a Pass/Fail question at settlement. The rubric is added to the queue's current version (build-set) — the set new cases are judged against; a queue only gets one after its first Agent-processed case settles, so this fails with 409 before then, and once the version holds 12 rubrics by default (25 on teams with the newer rubric generator enabled); the error message states the ceiling.

NameRequiredDescriptionDefault
titleYesShort, human-readable Pass/Fail rubric title.
queue_idYesThe queue's unique identifier
descriptionYesA 1-2 sentence Pass condition phrased as a question.

TDQS

A4.4/5.0
Behavior5/5

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

Annotations carry only the generic safety profile (readOnly=false, idempotent=false, destructive=false), and the description adds exactly the kind of context annotations cannot: the 409 precondition tied to first settled case, and the version-cap ceiling with its two values and the fact that the error message reports it. This is rich, non-obvious failure-mode disclosure.

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

Conciseness4/5

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

Front-loads the core action in the first sentence, then layers the definition and the two constraints. The single dense paragraph with em-dashes is information-rich but a touch packed; every clause still earns its place, so a 4 is fair.

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 create tool with no output schema, the description covers what is created, where it lands (current build-set version), the precondition for success, and the hard limit. Nothing an agent needs in order to call it correctly or interpret common failures is missing.

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%, and all three parameters (title, queue_id, description) are documented with lengths and format in the schema itself. The description adds conceptual meaning (Pass/Fail at settlement) but no per-parameter guidance beyond the schema, so the baseline 3 applies.

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?

States a specific verb ("Add") plus a precise resource ("one case-level evaluation rubric to a queue's current rubric set") and explains what a case-level rubric is judged against. An agent can distinguish it from sibling tools like createEvalRubric, replaceCaseQueueEvalRubrics, and updateCaseQueueEvalRubric without opening any schema.

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?

Gives clear situational context: the queue must already have settled an Agent-processed case or this fails with 409, and the version ceiling (12 by default, 25 with the newer generator) determines when additions stop. It does not, however, explicitly route the agent to alternatives like replaceCaseQueueEvalRubrics for bulk replacement, so it earns a 4 rather than 5.

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

createCasesCreate CasesAInspect

Create one or more cases in a queue. Provide either a single case object or a cases array (1-100); providing both returns 400. Each case takes a title (max 500 chars), optional labels that will be assigned to the case on creation (missing labels are created on the queue), and an optional priority (none, medium, or high; medium/high raise it above the default in the queue, none is the default; priority only affects the order pending cases are picked up in: due postponed cases are handled first, then higher priority). For the case payload, send free-form data OR a structured json_data object, never both, and a single request must be all free-text or all structured. json_data is validated against the queue's Case schema and requires the queue to have one; a schema-guarded queue accepts only json_data, while a queue without the guard also accepts free-text data. A guarded queue that has no schema yet accepts free-text data only when typed Case schemas are off for that queue — the team has them turned off AND the queue is not inside an automation (there is then no way to declare a schema, so the guard cannot apply). A queue inside an automation always has them on, so a guarded one refuses free-text data until its schema is declared.

NameRequiredDescriptionDefault
caseNo
casesNo
queue_idYesThe queue's unique identifier

TDQS

A4.7/5.0
Behavior5/5

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

The description extensively discloses behaviors: mutual exclusivity of case/cases and data/json_data, label creation on the queue, priority semantics affecting pending order, validation against the queue's Case schema, and the 400 error condition. Annotations already indicate this is a mutating, non-destructive operation; the description adds rich context about validation and side effects, exceeding what annotations provide.

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

Conciseness4/5

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

The description is long but well-structured, front-loading the core action and then detailing conditions and rules. Every sentence contributes necessary information for the tool's complexity. It could be more concise by trimming some conditional clauses, but the organization is logical and readable.

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?

Given the tool's complexity (nested objects, multiple exclusive modes, schema validation, priority behavior), the description covers all essential aspects: limits, error conditions, data format selection, and queue-specific rules. It doesn't describe return values, but no output schema exists and creation tools typically return minimal info; the description is sufficient for an agent to call it correctly.

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

Parameters5/5

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

Despite only 33% schema description coverage, the description explains the meaning and interaction of all key parameters: the case/cases structure, the 1-100 array limit, the mutual exclusivity of data and json_data, priority enum semantics, and label behavior. This adds substantial meaning beyond the schema's field descriptions, especially for the tricky conditional rules around schema-guarded queues.

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 clear, specific action: 'Create one or more cases in a queue.' This states the verb, resource, and context, and it differentiates from sibling tools like updateCase, deleteCase, and searchCases. The tool's purpose is unambiguous.

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?

While the description doesn't explicitly contrast with sibling tools, it provides detailed guidance on when to use a single case vs. an array, and when to use free-form data vs. structured json_data based on queue schema guards and automation context. This is strong usage guidance for the tool's own variants, though it omits explicit 'use this instead of X' guidance.

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

createClarityArtifactImportUploadUrlCreate Clarity Artifact Import Upload UrlAInspect

Create a signed upload URL for importing a Miro export into a Clarity v2 process. Supports SVG, XML, PNG, and JPEG exports. The caller must upload the file to the returned URL, then complete the import.

NameRequiredDescriptionDefault
file_nameYesName of the Miro export file. Supported extensions: .svg, .xml, .png, .jpg, .jpeg
process_idYesThe clarity process id
content_typeYesMIME type of the Miro export file
extra_capture_request_idNoOptional extra-capture-request id to bind this import to

TDQS

A4.2/5.0
Behavior4/5

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

The description discloses a non-obvious two-step behavior: this tool only creates the URL; the caller must separately upload and then complete the import. This goes beyond the minimal annotation set, which only says readOnlyHint=false and destructiveHint=false. It does not mention expiration or side effects, but the core workflow is transparent.

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

Conciseness5/5

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

Three sentences, each earning its place: the first states the operation, the second lists supported formats, and the third explains the required follow-up. The most important scoping information is front-loaded.

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

Completeness4/5

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

With no output schema, the description still makes clear that a URL is returned for uploading and that a completion step is required. It could name the exact complete-import sibling tool or describe the response shape, but the essential context for invocation and next steps is present.

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 schema already documents process_id, file_name, content_type, and extra_capture_request_id. The description reinforces the supported file types but does not add meaningful parameter semantics beyond what the schema provides. Baseline 3 is appropriate.

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 clearly states a specific verb, resource, and scope: 'Create a signed upload URL for importing a Miro export into a Clarity v2 process.' It names the supported formats and, by focusing on Miro artifacts, is distinguishable from sibling tools like createClarityDocumentUploadUrl and createClarityImageUploadUrl.

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?

The description gives clear workflow context: the caller must upload the file to the returned URL and then complete the import. It does not explicitly name alternatives or exclusion conditions, but the Miro/Clarity-v2 framing is specific enough to guide selection.

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

createClarityDocumentUploadUrlCreate Clarity Document Upload UrlBInspect

Create a signed URL for uploading a PDF, Word (.docx), TXT, Markdown, BPMN, XLSX, or CSV document directly to GCS

NameRequiredDescriptionDefault
idYesThe clarity process ID
fileNameYesName of the document file
contentTypeYesMIME type of the document
extraCaptureRequestIdNoExtra-capture-request id to bind this capture to

TDQS

B3.2/5.0
Behavior3/5

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

Annotations already declare readOnlyHint=false, idempotentHint=false, openWorldHint=false and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful non-obvious context: the URL is signed and the upload target is GCS directly. It omits URL expiration, HTTP method, and that a completion call is required, so it only partially exceeds the annotation floor.

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

Conciseness4/5

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

A single front-loaded sentence with the verb first and no boilerplate. The enumerated accepted formats partly duplicate the contentType enum, a minor redundancy, but the sentence still earns its place.

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

Completeness3/5

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

No output schema exists, so the description carries the burden of describing the return, and "signed URL" only hints at it. For an upload-flow tool it should mention expiry, upload method, and the completion step; given the annotations cover safety and the schema covers inputs, this is adequate but with clear gaps.

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 all four parameters (id, fileName, contentType, extraCaptureRequestId) are already documented, establishing a baseline of 3. The file-type list in the description loosely maps to the contentType enum but adds no format or constraint detail beyond it, and extraCaptureRequestId is never mentioned.

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

Purpose4/5

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

States a specific verb and resource ("Create a signed URL") scoped to Clarity document uploads, and the enumerated file types (PDF, docx, TXT, Markdown, BPMN, XLSX, CSV) signal that this is the document variant rather than image/video. It does not explicitly name createClarityImageUploadUrl, createClarityVideoUploadUrl, createClarityTeamDocumentUploadUrl, or createClarityOrganizationDocumentUploadUrl, which are easy to confuse given the crowded upload-url sibling set.

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

Usage Guidelines2/5

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

No when-to-use or when-not guidance, and no indication of the prerequisite (existing Clarity process id) or the required follow-up. The workflow implication that a signed URL must be followed by completeClarityDocumentUpload is absent, despite that sibling existing.

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

createClarityFolderCreate Clarity FolderCInspect

Create a process folder

NameRequiredDescriptionDefault
nameYesName of the folder to create.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

C2.9/5.0
Behavior2/5

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

The annotations already indicate this is not read-only, not idempotent, and not destructive, and the description adds no behavioral context beyond the word 'create.' It does not disclose side effects, naming collisions, permissions, or what kind of object is produced, so the description adds little beyond the structured metadata.

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

Conciseness4/5

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

The description is a single, efficient sentence with no filler or repetition. It is front-loaded and easy to parse, though it is minimal to the point of under-specification in other dimensions.

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

Completeness3/5

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

For a simple two-parameter create operation with a rich schema, the description is minimally adequate: the agent knows it creates a folder and needs a name. However, it lacks context about what a process folder is used for, whether folders are hierarchical, and what the tool returns, leaving some ambiguity for an agent navigating a large sibling toolset.

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 coverage is 100%, and the parameter descriptions already document the 'name' field and thoroughly explain 'team_id', including API-key and OAuth behavior. The tool description adds no extra parameter-level meaning, so the baseline score of 3 is appropriate.

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

Purpose4/5

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

The description states a clear action and object: 'Create a process folder.' It is not a tautology and the verb 'create' maps directly to the tool's function. However, it does not differentiate from sibling folder tools such as createAgentFolder or clarify what a 'process folder' is within the Clarity domain.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives like createAgentFolder, setupClarityFoldersFromLandscape, or updateClarityFolder. There is no mention of prerequisites, team context, or folder hierarchy, leaving the agent to infer usage from the name alone.

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

createClarityGuidanceCreate Clarity GuidanceCInspect

Create a new automation guidance message for a clarity process

NameRequiredDescriptionDefault
idYesThe clarity process ID
contentYesAutomation guidance to add to the process.

TDQS

C2.8/5.0
Behavior2/5

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

Annotations indicate readOnlyHint=false and destructiveHint=false, so the tool is understood to mutate state, but the description adds no behavioral context: it does not state whether creation is idempotent, whether it appends to existing guidance, what side effects occur, or what happens on duplicate IDs. For a mutation tool with minimal annotation detail, this is a significant gap.

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

Conciseness3/5

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

The description is a single concise sentence, which is efficient. However, it is a near-restatement of the tool name and title, providing little additional value beyond what the structured metadata already conveys.

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

Completeness2/5

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

The tool has two required parameters and no output schema, and the description omits important context such as whether the guidance is appended or replaces existing guidance, whether a clarity process must already exist, or what the response/result indicates. The description is minimally adequate for basic invocation but incomplete for confident use.

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 coverage is 100%, so the schema already documents both parameters and their types. The description adds the phrase 'automation guidance message', slightly clarifying the content field's purpose, but does not add meaning beyond the schema's own descriptions.

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

Purpose4/5

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

The description states a specific verb ('Create') and resource ('automation guidance message for a clarity process'), making the basic action clear. However, it does not distinguish itself from sibling create_* tools or from updateClarityGuidance, and the term 'clarity process' is domain-specific without elaboration.

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

Usage Guidelines2/5

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

No guidance is given about when to use this tool versus updateClarityGuidance or other createClarity* tools. The context of a clarity process and automation guidance is implied by the name and schema, but there is no explicit usage context, prerequisites, or alternatives.

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

createClarityImageUploadUrlCreate Clarity Image Upload UrlAInspect

Create a signed URL for uploading a PNG, JPEG, WebP, or SVG image directly to GCS

NameRequiredDescriptionDefault
idYesThe clarity process ID
fileNameYesName of the image file
contentTypeYesMIME type of the image
extraCaptureRequestIdNoExtra-capture-request id to bind this capture to

TDQS

A3.8/5.0
Behavior3/5

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

Annotations mark the tool as readOnlyHint=false and destructiveHint=false, so the description carries the burden of explaining behavior. It states the tool creates a signed URL for direct GCS upload, which implies the actual upload happens client-side, but it does not disclose URL expiry, return format, or other side effects. This is adequate but not rich.

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

Conciseness5/5

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

The description is a single sentence with zero filler. The core action ('Create a signed URL') and key scope (image formats, GCS) are concentrated and front-loaded. This is ideal for a low-complexity utility tool.

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

Completeness4/5

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

For a straightforward utility with fully documented parameters and no output schema, the description covers the essential purpose and scope. It could explicitly note that this only generates the URL without uploading the image, but that is already implied by 'signed URL for uploading'. The optional extraCaptureRequestId is documented in schema, so nothing essential is missing.

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% – all parameters (id, fileName, contentType, extraCaptureRequestId) are documented in the schema. The description adds no additional parameter-level meaning beyond what is already in the schema, so the baseline of 3 applies.

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 clearly states the action ('Create a signed URL'), the resource (an image upload URL), and the scope (PNG, JPEG, WebP, SVG images, direct to GCS). This distinguishes it from sibling URL creators like createClarityDocumentUploadUrl or createClarityVideoUploadUrl by explicitly listing image formats, so an agent can reliably identify it.

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

Usage Guidelines3/5

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

The description implies usage through the listed image formats, but it gives no explicit guidance on when to prefer this tool over siblings like createFileUploadUrl or createClarityDocumentUploadUrl. There are no alternative names or exclusion conditions. The agent must infer the use case from the format list alone.

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

createClarityLandscapeNodeCreate Clarity Landscape NodeAInspect

Create an area folder in the process tree. An active area (the default) requires organization admin+ or manager+ on a team of the organization; a "proposal" area may be added by any organization member.

NameRequiredDescriptionDefault
nameYes
orgIdYes
parentIdNo
ownerLabelNo
descriptionNoOne or two sentences saying what family of work this area groups. Persisted as the area's summary.
creationModeNoUse "proposal" to add an area for review instead of asserting it exists. A proposal is idempotent: an equivalent live area under the same parent is returned untouched rather than duplicated. Defaults to "active".

TDQS

A3.9/5.0
Behavior4/5

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

Annotations only declare the write flags; the description adds the real behavioral constraint — the authorization tiers required for an active area versus a proposal. It does not mention side effects of creating an active area (duplicate detection, whether an existing area is returned), which the schema partially covers.

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

Conciseness5/5

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

Two sentences, no filler, with the core action front-loaded and the mode/permission caveat immediately after. Every clause carries information an agent needs.

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

Completeness3/5

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

For a mutation tool with no output schema and six parameters, the description covers permissions and mode selection but leaves the hierarchy semantics (parentId null behavior) and the result of the call unaddressed. Adequate but with visible gaps.

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 coverage is only 33%, so the description must carry more weight than it does. It explains creationMode well (default, what proposal means, permission implications) but adds nothing about parentId (is null the root?), ownerLabel, orgId, or name constraints.

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

Purpose4/5

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

States a specific verb and resource: 'Create an area folder in the process tree.' An agent can tell what object is produced, though the description does not explicitly distinguish this from near-siblings like createClarityFolder or createClarityProcessNode.

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?

Gives a concrete decision rule for the active vs proposal modes tied to permissions, which is exactly the branch an agent must choose. It stops short of naming alternative tools (e.g. proposeClarityLandscapeProcess) for when a proposal is the better route.

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

createClarityOrganizationDocumentUploadUrlCreate Clarity Organization Document Upload UrlBInspect

Create a signed URL for uploading a PDF, Word (.docx), TXT, Markdown, or BPMN document as an organization-level Clarity capture

NameRequiredDescriptionDefault
orgIdYes
fileNameYesName of the document file
contentTypeYesMIME type of the document

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already declare a non-destructive, non-idempotent, closed-world write. The description adds useful context (it returns a signed URL, and only five document formats are accepted), but omits whether the URL expires, what auth/permissions are needed, and why calls are non-idempotent (each call mints a new URL).

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

Conciseness5/5

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

Single front-loaded sentence, no filler, and the scope qualifier ('organization-level') arrives before the trailing details. Every phrase earns its place.

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

Completeness3/5

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

For a mutation with no output schema, the description conveys the core action and format constraints but leaves the two-step upload workflow unspecified: it never says the returned signed URL must be used to PUT the file and then finalized via completeClarityOrganizationDocumentUpload, nor does it mention URL lifetime.

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

Parameters4/5

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

Schema coverage is 67%, so the schema documents fileName and contentType. The description earns extra credit by mapping the raw MIME enum to human-readable formats, notably clarifying that BPMN corresponds to application/xml, which is not obvious from the enum alone. orgId remains undocumented anywhere but is self-describing.

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

Purpose4/5

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

States a specific verb (Create) and resource (signed URL for document upload) and scopes it as 'organization-level Clarity capture', which separates it from the team-level and unqualified document-upload siblings. It does not explicitly name or contrast those siblings, but the scope qualifier is enough to route an agent correctly.

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

Usage Guidelines2/5

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

No guidance on when to choose this over createClarityDocumentUploadUrl or createClarityTeamDocumentUploadUrl, and no mention of the required follow-up step (completeClarityOrganizationDocumentUpload). Usage is only implied by the phrase 'organization-level'.

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

createClarityProcessCreate Clarity ProcessAInspect

Create a new Clarity v2 process for the current team (Builder+). Optional name defaults server-side when omitted. Response uses camelCase createdAt to match existing FE clients.

NameRequiredDescriptionDefault
nameNoOptional process name; server default applies when omitted
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A3.7/5.0
Behavior3/5

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

The annotations only declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, and openWorldHint=false. The description adds useful behavior beyond those: optional name defaults server-side, and the response uses camelCase createdAt for existing FE clients. However, it does not disclose potential side effects, error behavior, or what else the response contains, so the added transparency is modest.

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

Conciseness5/5

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

The description is two sentences with no filler. The first sentence front-loads the core action and scope, and the second covers the only server-side default plus a response-format note. Every sentence contributes actionable information.

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

Completeness3/5

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

For a create tool with two optional parameters and no output schema, the description covers the basic purpose, team scope, name default, and one response-format detail. However, the full return payload is only hinted at via 'createdAt', and failure conditions such as team mismatch are only present in the schema. It is adequate but not complete.

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%, and the schema already documents both parameters thoroughly, including the team_id pinned-team fallback and OAuth behavior. The description only repeats the name defaulting and omits team_id entirely, so it adds no meaningful parameter semantics beyond the schema. Baseline 3 is appropriate.

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 states a specific action and resource: 'Create a new Clarity v2 process for the current team (Builder+)'. This unambiguously distinguishes the tool from sibling tools like duplicateClarityProcess, createClarityProcessLabel, and createClarityProcessNode. The 'v2' and 'current team (Builder+)' qualifiers add useful precision.

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

Usage Guidelines3/5

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

The description implies the primary use case (creating a new Clarity process) and notes the team scope, but it does not explicitly compare against alternatives like updateClarityProcess or duplicateClarityProcess, nor does it state when not to use this tool. The context is clear enough to infer usage, but no direct routing guidance is provided.

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

createClarityProcessLabelCreate Clarity Process LabelCInspect

Create process tags for an organization.

NameRequiredDescriptionDefault
orgIdYes
valueYes
colorHueNo

TDQS

C2.8/5.0
Behavior2/5

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

Annotations already indicate this is a non-read-only write operation, and the description adds little beyond that. It does not disclose side effects, permissions, uniqueness behavior, default colorHue application, or whether the operation is idempotent despite the idempotentHint being false.

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

Conciseness5/5

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

The single sentence is front-loaded and contains no filler. Every word adds meaning: the action, the resource type, and the organizational scope are all present.

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

Completeness2/5

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

The tool has three parameters, no output schema, and minimal annotations, so the description carries a heavy burden. It fails to mention what the tool returns, how colorHue is used, what happens on duplicate values, or any prerequisites, leaving an agent under-equipped to invoke it correctly.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate, but it only loosely maps 'organization' to orgId and 'tags' to value. colorHue is completely absent from the description, and no parameter-level constraints or defaults are explained.

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

Purpose4/5

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

The description states a specific action ('Create'), a clear resource ('process tags' / Clarity Process Label), and a scope ('for an organization'). This distinguishes it from related tools like assignClarityProcessLabels, updateClarityProcessLabel, and deleteClarityProcessLabel, though it doesn't explicitly name them.

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

Usage Guidelines2/5

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

No guidance is given on when to use this tool versus alternatives such as listAvailableClarityProcessLabels, assignClarityProcessLabels, or updateClarityProcessLabel. The description only implies creation, but doesn't address reuse, duplication, or relationship to process-process label assignment.

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

createClarityProcessNodeCreate Clarity Process NodeAInspect

File an existing Clarity process into an area of the process landscape (team builder or organization admin+). Use this for a process that already exists but sits in Unsorted; use proposeClarityLandscapeProcess to create a brand-new one.

NameRequiredDescriptionDefault
orgIdYes
parentIdYesThe area folder the process is filed under.
processIdYesAn existing Clarity process to file into the landscape. Unsorted processes are listed as `unlinkedProcesses` by getClarityProcessLandscape.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare this is a non-read-only, non-destructive, non-idempotent mutation. The description adds value beyond that by disclosing the authorization requirement ("team builder or organization admin+") and the precondition that the process must be in Unsorted, though it does not describe side effects on failure or re-run behavior.

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

Conciseness5/5

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

Two tight sentences: the action and destination come first, then the when-to-use/alternative guidance. The role parenthetical is the only slightly heavy element, and nothing is wasted.

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

Completeness4/5

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

For a simple 3-parameter mutation with no output schema, the description covers purpose, when-to-use, the alternative, the permission gate, and the precondition. It stops short of describing return/confirmation behavior or error conditions, which are the only remaining gaps.

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 coverage is 67% — parentId and processId carry schema descriptions, but orgId is undocumented in both schema and description. The description reinforces the meaning of processId (an existing/Unsorted process) and parentId (the filing area) but does not map parameters explicitly, so it only marginally exceeds the schema baseline.

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?

States a specific verb ("File") and resource (an existing Clarity process) and the destination (an area of the process landscape), which the tool name ("createClarityProcessNode") does not make obvious. It also explicitly distinguishes itself from proposeClarityLandscapeProcess, so an agent can route correctly without opening a schema.

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

Usage Guidelines5/5

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

Gives an explicit use condition ("a process that already exists but sits in Unsorted") and names the alternative tool (proposeClarityLandscapeProcess) with the condition that selects it ("brand-new one"). It even states the required role (team builder or organization admin+), leaving little to inference.

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

createClarityTeamDocumentUploadUrlCreate Clarity Team Document Upload UrlAInspect

Create a signed URL for uploading a PDF, Word (.docx), TXT, Markdown, or BPMN document as a team-level Clarity capture

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
fileNameYesName of the document file
contentTypeYesMIME type of the document

TDQS

A3.5/5.0
Behavior3/5

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

Annotations already declare this is a non-read-only, non-idempotent, non-destructive write. The description adds the accepted document types and that the capture is team-scoped, which is useful context, but omits URL expiry, permission requirements, and the fact that nothing is persisted until the upload is completed. Some added value against a lower annotation bar.

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

Conciseness5/5

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

A single front-loaded sentence with no filler. The supported formats and scope are packed in without any redundant restatement of the name.

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

Completeness3/5

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

For a 3-parameter tool with no output schema, the safety profile and parameters are covered by annotations and schema. What is missing is the multi-step contract — that the returned signed URL must be used to upload and then finalized via completeClarityTeamDocumentUpload — which an agent needs to complete the workflow correctly.

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 fileName, contentType, and team_id are already fully documented in the schema, including the API-key-vs-OAuth team pinning rule. The description adds nothing beyond what the schema provides, matching the baseline for high coverage.

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

Purpose4/5

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

Specific verb (create) plus a precise resource (signed URL for document upload) and a stated scope (team-level Clarity capture). The "team-level" qualifier implicitly separates it from createClarityDocumentUploadUrl and createClarityOrganizationDocumentUploadUrl, but those siblings are never named. Clear purpose, however the differentiation is left to inference via the name.

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

Usage Guidelines3/5

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

The upload-URL phrasing implies a create-then-upload flow, but the description never states when to choose this over the other document-upload-URL siblings or that a follow-up call (completeClarityTeamDocumentUpload) is required. Usage is implied rather than guided.

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

createClarityVideoUploadUrlCreate Clarity Video Upload UrlAInspect

Create a signed URL for uploading a video file directly to GCS

NameRequiredDescriptionDefault
idYesThe clarity process ID
fileNameYesName of the video file
contentTypeYesMIME type of the video
extraCaptureRequestIdNoExtra-capture-request id to bind this capture to

TDQS

A4/5.0
Behavior4/5

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

The annotations only provide generic flags (readOnlyHint=false, destructiveHint=false) and do not explain the operation's nature. The description adds meaningful behavioral context: the tool does not upload the video itself but returns a signed URL, and the upload is performed directly to GCS. This helps the agent understand the expected flow, though expiration or lifecycle details are not disclosed.

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

Conciseness5/5

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

The description is a single, focused sentence that states the core purpose and the key storage destination ('directly to GCS'). There is no filler, repetition, or unnecessary detail, making it easy for an agent to parse quickly.

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

Completeness4/5

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

For a simple four-parameter tool with no nested objects, the schema fully documents inputs and the description explains the output concept ('signed URL') and the storage target. The main missing piece is explicit guidance on the follow-up completion flow, but the description is complete enough to select and invoke the tool correctly.

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%, with all four parameters already documented meaningfully in the schema (id, fileName, contentType, extraCaptureRequestId). The description does not add parameter-specific detail beyond referring to 'uploading a video file', which the schema already captures. A baseline score of 3 is appropriate because the schema carries the parameter documentation burden.

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 names a specific verb ('Create'), a specific resource ('a signed URL'), and a specific context ('uploading a video file directly to GCS'). This clearly distinguishes it from sibling upload-URL tools like createClarityImageUploadUrl, createClarityDocumentUploadUrl, and createFileUploadUrl without requiring the agent to inspect schemas.

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

Usage Guidelines3/5

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

The description implies the usage context: this is the URL-generation step before a video is uploaded directly to GCS, and the sibling completeClarityVideoUpload suggests a follow-up step. However, it does not explicitly say when to choose this over other upload-URL tools or mention the completion step, so the usage guidance remains implicit rather than explicit.

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

createConnectionCreate ConnectionBInspect

Create a new user-provided connection (custom MCP server) for the current team. OAuth-based integrations (native) require an interactive browser flow — start them with the dedicated OAuth endpoints (/v2/teams/:team_id/connections/oauth/native/:provider/start or /v2/teams/:team_id/connections/oauth/mcp/start) instead of calling this endpoint directly.

NameRequiredDescriptionDefault
nameYes
typeNocustom_mcp
headersNo
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
providerYes
server_urlNo
auth_methodYes
custom_integration_idNo

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already establish that this is a non-read-only, non-idempotent mutation. The description adds useful context that the tool creates a custom MCP connection and that OAuth flows need different endpoints. It does not disclose side effects, failure behavior, or what happens when auth_method is set to oauth, but with annotations present this is a moderate level of transparency.

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

Conciseness5/5

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

The description is two sentences with the core purpose front-loaded. The caveat about OAuth flows is placed immediately after the main statement, and the explicit endpoint paths add practical value without excessive verbosity.

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

Completeness2/5

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

Given 8 parameters, a nested headers object, an auth_method enum that includes oauth, and no output schema, the description is not complete enough. It leaves unclear how auth_method interacts with the warning about OAuth flows, what server_url and headers mean for a custom MCP server, and what response or validation behavior to expect. The tool needs more behavioral and parameter context to be safely invoked.

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

Parameters2/5

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

Schema description coverage is only 13%, and the description provides almost no parameter-level guidance. It does not explain name, server_url, headers, auth_method, or custom_integration_id beyond what the bare schema types and enum imply. The team_id parameter is well described in the schema, but most required and optional parameters remain semantically opaque.

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

Purpose4/5

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

The description states a clear verb-resource pair: "Create a new user-provided connection (custom MCP server) for the current team." It names the resource type, the scope (team), and clarifies that this is specifically for custom MCP servers. It also explicitly contrasts with OAuth-based integrations, though it doesn't differentiate from closely named siblings like createCustomIntegration or createCredential.

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?

The description explicitly tells agents when NOT to use this tool: OAuth-based integrations with an interactive browser flow should use the dedicated OAuth endpoints instead, and it names those endpoints. However, it doesn't provide guidance for choosing between this and other connection-related siblings such as createCredential, createCustomIntegration, or probeMcpServer.

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

createCredentialCreate credentialAInspect

Create a login. At least one of password or otp_secret must be provided. Personal by default; pass shared: true to create a team-shared login (requires lead builder role).

NameRequiredDescriptionDefault
domainYes
sharedNo
userIdYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
passwordNo
usernameNo
otp_secretNo

TDQS

A3.7/5.0
Behavior4/5

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

Annotations only establish that this is a mutating, non-idempotent operation. The description adds useful behavioral context: personal-by-default sharing behavior, the lead-builder role gate for shared logins, and the at-least-one validation constraint. These details go beyond what annotations alone reveal.

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

Conciseness5/5

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

Three short sentences front-load the purpose, then state the required combination constraint and the shared-mode behavior/role requirement. Every sentence earns its place with no redundant wording.

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

Completeness3/5

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

The definition is minimally sufficient for a basic personal credential: required fields are visible in the schema, the validation rule is explicit, and the shared path is explained. However, with no output schema and no description of what userId/domain represent, the agent must infer important invocation details rather than being told them.

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 only 14%, so the description must carry param semantics. It explains shared, password, and otp_secret meaningfully, but leaves the required userId and domain parameters unexplained, and also doesn't clarify username. This is a partial compensation for a 7-parameter tool.

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

Purpose4/5

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

The description states a specific action and resource ('Create a login') and clarifies that a credential is a login rather than a generic secret or connection. It doesn't explicitly name a sibling alternative, but the resource type is specific enough to distinguish it from tools like createSecret or updateCredential.

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

Usage Guidelines3/5

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

The description gives clear parameter-level guidance: at least one of password or otp_secret is required, and shared: true is the switch for team-shared logins with a role requirement. However, it doesn't say when to prefer this tool over related alternatives like updateCredential or createSecret, so the tool-selection guidance is mostly implied.

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

createCustomIntegrationCreate Custom IntegrationAInspect

Create a custom integration type (team-level catalog entry) that users can then connect as user-provided MCP connections. Requires manager-or-above role.

NameRequiredDescriptionDefault
nameYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
server_urlYes
auth_methodYes
oauth_client_idNo
oauth_client_secretNo

TDQS

A4/5.0
Behavior4/5

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

Annotations already signal readOnly=false, idempotent=false, and destructive=false, so the write behavior is known. The description adds valuable behavioral context beyond annotations: the created entity is a team-level catalog entry, the operation requires manager-or-above permissions, and users will later connect it as an MCP connection. This is meaningful for an agent deciding whether to call 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.

Conciseness5/5

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

The description is a single, dense sentence with no filler or repetition. The verb and resource are front-loaded, and the role requirement is appended without bloating the text. Every part earns its place.

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

Completeness3/5

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

The description is sufficient to understand the high-level purpose and permission requirement, but it does not cover parameter dependencies such as when oauth_client_id and oauth_client_secret are needed, nor does it clarify the server_url/auth_method semantics. With no output schema and only 17% schema description coverage, the definition is minimally viable but has clear gaps.

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

Parameters2/5

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

Schema description coverage is only 17%, with team_id carrying the sole description. The tool description does not explain server_url, auth_method, oauth_client_id, oauth_client_secret, or how they relate to each other. Since the schema leaves most parameters undescribed, the description needed to compensate but does not.

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 states a specific action ('Create'), a specific resource ('custom integration type'), and adds a clarifying parenthetical ('team-level catalog entry') that distinguishes it from a concrete connection. The follow-up clause about users connecting them as user-provided MCP connections makes the tool's purpose unmistakable and separates it from sibling tools like createConnection.

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?

The description gives clear context: this creates a reusable catalog entry rather than an actual connection, and it requires a manager-or-above role. It does not explicitly name alternatives or say 'when not to use', but the catalog-vs-connection framing provides enough guidance for an agent to select it appropriately.

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

createEvalRubricCreate Eval RubricAInspect

Add one Agent-specific evaluation rubric to a build. A build may hold at most 5 custom rubrics by default (25 on teams with the newer rubric generator enabled); this fails with 409 once the build's ceiling is reached, and the error message states it. Defaults to the Agent's live build; pass build_id to target a specific revision.

NameRequiredDescriptionDefault
titleYesShort, human-readable Pass/Fail rubric title.
agentIdYesThe agent's unique identifier (Assignment ID)
build_idNoAdd the rubric to this build (revision). Defaults to the agent's live build when omitted.
descriptionYesA 1-2 sentence Pass condition phrased as a question.
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare the write/safety profile (readOnlyHint=false, idempotentHint=false), and the description adds substantial context beyond them: the 5/25 rubric ceiling per build, the 409 error on overflow, and the live-build default. It does not describe the success response or permission requirements, but discloses meaningful limits and failure modes.

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

Conciseness5/5

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

Two dense sentences, front-loaded with the action, then the capacity/error constraint, then the targeting default. Every clause carries information and nothing is wasted.

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

Completeness4/5

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

For a mutation tool with no output schema, the description covers the key behavioral constraints an agent needs (limits, 409, default target). It omits the success return shape and any auth prerequisites, but the annotations and full schema coverage fill most remaining gaps.

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 all five parameters are documented in the schema itself, including build_id's live-build default and the intricate selected_automation_revision_id semantics. The description only restates the build_id default, adding little beyond the schema.

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?

States a specific verb and resource ('Add one Agent-specific evaluation rubric to a build') with the qualifier 'Agent-specific' that distinguishes it from sibling rubric tools like createCaseQueueEvalRubric. An agent can tell what this creates and where it lands.

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?

Gives clear context: defaults to the Agent's live build, pass build_id to target a specific revision. It explains the capacity ceiling and the resulting 409 failure. It does not name alternative tools (updateEvalRubric, replaceEvalRubrics), but usage context is clear.

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

createFileUploadUrlCreate File Upload UrlBInspect

Generate a signed URL for uploading a file directly to GCS.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
fileNameYesName of the file to upload
contentTypeYesMIME type of the file

TDQS

B3.3/5.0
Behavior3/5

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

The description adds some behavioral context beyond the annotations by indicating that this generates a signed URL for direct GCS upload, implying the actual file transfer happens client-side. However, it does not disclose URL expiry, required permissions, or what happens after generation. Annotations are not contradicted.

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

Conciseness5/5

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

The description is a single, front-loaded sentence with no filler. 'Generate a signed URL' appears first, followed by the purpose qualifier 'for uploading a file directly to GCS,' and every word earns its place.

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

Completeness3/5

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

The tool is simple and the schema fully documents all parameters, so the description is mostly adequate for invoking it. However, the large sibling set creates ambiguity about when this generic upload URL tool should be chosen over domain-specific ones, and the absence of an output schema leaves return-value details unstated.

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 parameters fileName, contentType, and team_id are already fully documented in structured form. The description contributes no additional parameter-level meaning beyond referring to 'a file.'

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

Purpose4/5

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

The description states a specific verb and resource: generate a signed URL for uploading a file directly to GCS. It is clear about what the tool does, though it does not distinguish itself from the many sibling create*UploadUrl tools.

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

Usage Guidelines2/5

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

No guidance is provided about when to use this tool versus alternatives like createCaseAttachmentUploadUrl, createClarityDocumentUploadUrl, or createSandboxUploadUrl. The description gives context but no explicit or implicit selection criteria beyond 'file directly to GCS.'

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

createOrgTeamCreate Org TeamAInspect

Create a new team under an organization you administer. Requires an organization Admin, Executive, or Owner role.

NameRequiredDescriptionDefault
nameYes
orgIdYesOrganization ID

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already indicate a non-read-only, non-idempotent, non-destructive mutation, and the description adds the authorization requirement (Admin/Executive/Owner) plus the constraint that the organization must be one the caller administers. This goes beyond what the schema or annotations say, and there is no contradiction with the annotations.

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

Conciseness5/5

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

Two sentences with no filler: the action is stated first, and the required role is stated second. Every sentence carries information an agent needs.

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

Completeness4/5

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

For a 2-parameter create operation with no nested objects or output schema, this covers action, target scope, and authorization adequately. It does not describe duplicate-name behavior or return value, but those are minor at this complexity level.

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?

Only orgId has a schema description; name has just type and minLength. The description maps both parameters implicitly—name is the new team's name and orgId is the target organization—but it does not explain naming constraints or uniqueness behavior, so compensation is partial.

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 the verb 'Create' and a specific resource, 'a new team under an organization,' which is exactly what the tool does. It also narrows scope to organizations the caller administers, which distinguishes it from generic team/invite-related siblings like createTeamInvite and inviteOrgMember.

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 an explicit precondition: only organization Admins, Executives, or Owners should call this. It does not name an alternative tool for other roles or for listing teams, but the resource and role context make the intended use clear.

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

createPulseDashboardCreate Pulse DashboardAInspect

Create a new Duvo Pulse dashboard from a natural-language prompt (e.g. 'open cases by queue this week') and dispatch the first generation turn. Generation is asynchronous — poll GET /artifacts/{artifactId} until status is completed. The dashboard is private to you unless you set visibility to 'team', which shares it with your whole team straight away — with permission 'view' (teammates see the dashboard) or 'edit' (teammates can also iterate on it).

NameRequiredDescriptionDefault
messageYes
permissionNo
visibilityNo
connection_idsNo

TDQS

A4/5.0
Behavior4/5

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

Annotations establish that this is a non-read-only, non-idempotent create operation, and the description adds valuable behavior beyond that: generation is asynchronous, requires polling GET /artifacts/{artifactId}, and visibility/permission defaults to private unless team sharing is chosen. It does not contradict the annotations.

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

Conciseness5/5

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

Three sentences, each earning its place: the core create action, the async polling behavior, and the privacy/permission model. The most important information is front-loaded and there is no filler.

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

Completeness4/5

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

For a create operation with no output schema, the description covers the core task, async generation, polling endpoint, and team-sharing semantics. It is slightly incomplete because it does not explicitly state what the initial response contains (e.g. artifactId) or what connection_ids does, but these are inferable or optional.

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?

With 0% schema description coverage, the description must explain the parameters, and it does explain message via the natural-language-prompt example, plus visibility and permission semantics. However, it never mentions connection_ids, leaving the agent to guess its role from the schema alone.

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 action ('Create a new Duvo Pulse dashboard'), specifies the input mode ('from a natural-language prompt'), and states the follow-up behavior ('dispatch the first generation turn'). This clearly distinguishes it from sibling tools like sendPulseDashboardMessage or answerPulseDashboardQuestion, which operate on an existing dashboard.

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

Usage Guidelines3/5

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

The description implies when to use it — when a new dashboard is needed from a prompt — but never names an alternative or an exclusion. There is no explicit guidance such as 'use updatePulseDashboard for existing dashboards' or 'use sendPulseDashboardMessage to continue a conversation.'

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

createPulseDashboardAttachmentUploadUrlCreate Pulse Dashboard Attachment Upload UrlAInspect

Issue a presigned upload URL for a file to attach to a Duvo Pulse dashboard message (e.g. an HTML dashboard to copy, or a screenshot to match). POST the file bytes to the returned upload_url as multipart form data under the field name 'file', then pass the returned attachment_id in the attachments array of POST /artifacts/{artifactId}/messages. The agent reads the file directly from its sandbox. Files live as long as the dashboard's sandbox (about 12 hours), so upload shortly before sending.

NameRequiredDescriptionDefault
filenameYesName of the file being attached, without any path segments
mime_typeYesMIME type of the file, e.g. text/html or image/png
artifactIdYes
size_bytesYesSize of the file in bytes (max 25MB)

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already show readOnlyHint=false and idempotentHint=false, but the description adds meaningful behavioral context: the URL is presigned, the file is read directly from the agent's sandbox, and files expire with the dashboard's sandbox in about 12 hours. This goes beyond the structured annotation fields without contradicting them.

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

Conciseness5/5

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

Three sentences with no filler: purpose, exact upload protocol, and lifetime warning. The critical usage constraint is front-loaded, and every sentence contributes actionable information.

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?

There is no output schema, but the description explicitly names both returned values (upload_url and attachment_id) and explains how to use them. It also covers the file lifetime and sandbox context. For a 4-parameter upload tool, this is complete enough for an agent to call and act on the result.

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 75%, so the schema already documents filename, mime_type, and size_bytes. The description adds that artifactId is used in the messages path and that the multipart field must be named 'file', which is useful but does not deeply explain each parameter. Baseline 3 is appropriate.

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 states a specific verb and resource: 'Issue a presigned upload URL for a file to attach to a Duvo Pulse dashboard message.' It also gives concrete examples (HTML dashboard, screenshot) and the tool name alone distinguishes it from sibling upload tools like createCaseAttachmentUploadUrl or createSandboxUploadUrl.

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?

The description gives a clear workflow: POST the file as multipart form data to the returned upload_url, then pass the attachment_id to POST /artifacts/{artifactId}/messages. It explicitly advises uploading shortly before sending due to the 12-hour lifetime. It does not explicitly compare against sibling upload-URL tools, but the intended context is clear.

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

createPulseDashboardCommentCreate Pulse Dashboard CommentAInspect

Start a comment thread on a Duvo Pulse dashboard (requires view access). Pass element — captured from the dashboard canvas — to pin the thread to one element; omit it for a comment on the dashboard as a whole.

NameRequiredDescriptionDefault
bodyYes
elementNo
artifactIdYes
revision_idNo

TDQS

A3.7/5.0
Behavior3/5

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

Annotations already indicate this is not read-only (readOnlyHint: false). The description adds the 'requires view access' constraint, which is useful, but it does not describe what the operation returns or any side effects beyond creating a thread. Given annotation coverage of the write nature, this is adequate but not rich.

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

Conciseness5/5

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

The description is two sentences, directly stating the purpose and the key parameter behavior. There is no redundancy or irrelevant information; every word adds value.

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

Completeness2/5

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

The description omits essential context for the required parameters (`artifactId` and `body`) and does not mention how the thread is associated with the dashboard. While it covers the element-to-dashboard distinction, it leaves users to infer the meaning of required fields, making it incomplete for a create operation.

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

Parameters2/5

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

Schema description coverage is 0%, and the description only explains the `element` parameter. It does not clarify `artifactId` or `body`, which are required. With four parameters and zero schema descriptions, the description fails to compensate for the missing semantics of the required fields.

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 clearly states the action ('Start a comment thread'), the resource ('Pulse dashboard'), and the key behavior of the `element` parameter. It distinguishes this tool from related actions like replying to a comment, making the purpose unambiguous.

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 explicitly mentions the view access requirement and explains the conditional use of `element` (pass for element-level, omit for dashboard-level). However, it does not explicitly contrast with alternatives like createPulseDashboardCommentReply, leaving the choice slightly implicit.

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

createPulseDashboardCommentReplyCreate Pulse Dashboard Comment ReplyAInspect

Reply to a comment thread on a Duvo Pulse dashboard (requires view access). commentId must be a thread root; threads are one level deep. A thread already marked complete still accepts replies and stays complete.

NameRequiredDescriptionDefault
bodyYes
commentIdYes
artifactIdYes

TDQS

A4.4/5.0
Behavior5/5

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

Annotations only state readOnlyHint:false and destructiveHint:false, leaving behavioral disclosure to the description. The description adds valuable context: 'requires view access' (permission requirement), 'threads are one level deep' (structural constraint), and 'a thread already marked complete still accepts replies and stays complete' (a non-obvious behavior). No contradiction with annotations.

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

Conciseness5/5

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

Three concise sentences with no filler. The primary purpose is front-loaded ('Reply to a comment thread'), followed by essential constraints and behavioral quirks. Every sentence earns its place.

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

Completeness4/5

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

For a low-complexity tool with three flat parameters and no output schema, the description covers the core purpose, a critical parameter constraint, and a behavioral edge case. It does not describe body or artifactId explicitly, but these are reasonably inferable from context. Overall adequate for an agent to call it correctly.

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 0%, so the description must explain parameters. It does clarify that commentId must be a thread root, which is useful. However, body and artifactId are left entirely to inference (body is likely the reply text, artifactId likely the dashboard identifier). Given the 0% coverage, the description only partially compensates.

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: 'Reply to a comment thread on a Duvo Pulse dashboard.' This clearly distinguishes it from sibling tools like createPulseDashboardComment (which creates a new thread) and sendPulseDashboardMessage (for dashboard messages). It also notes the one-level-deep thread structure, reinforcing that this is strictly a reply operation.

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?

The description makes it clear this is for replying to an existing thread, which implies when to use it. However, it does not explicitly name alternatives (e.g., 'Use createPulseDashboardComment for new threads') or state when not to use it. The constraint on commentId being a thread root provides practical guidance but not tool-selection guidance.

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

createQueueCreate QueueCInspect

Create a new queue.

NameRequiredDescriptionDefault
nameYesQueue name. A standalone queue must be uniquely named within the team. A queue created inside an automation instead has to be uniquely named within a revision, which is checked when that revision is activated.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
folder_idNoOptional folder to nest the queue under.
descriptionNoOptional human-readable description.
automation_idNoAutomation this queue belongs to. Optional for teams not yet migrated to Automations; required once a team has migrated.

TDQS

C2.9/5.0
Behavior2/5

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

The annotations already indicate readOnlyHint=false, destructiveHint=false, and idempotentHint=false, so the agent knows this is a non-read-only operation. The description adds no additional behavioral detail about side effects, idempotency implications, permissions, or failure modes. It contributes nothing beyond the annotations already provide.

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

Conciseness4/5

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

The description is a single sentence with no filler, and the core action 'Create a new queue' is front-loaded. It is appropriately concise, though it sacrifices useful context that would justify a perfect score.

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

Completeness2/5

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

With five parameters, no output schema, and many queue-related sibling tools, a single generic sentence is insufficient for an agent to fully understand the operation's context, return value, or prerequisites. The schema fills in some gaps, but the description alone is inadequate for complete tool selection and invocation.

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?

The input schema has 100% description coverage for all five parameters, including detailed notes on name uniqueness, team_id fallback behavior, and automation_id migration requirements. The description itself adds no parameter-level information, but the schema fully carries that burden, so the baseline score of 3 is appropriate.

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

Purpose4/5

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

The description 'Create a new queue' clearly identifies the action (create) and the target resource (queue), making it distinct from similar siblings like createQueueAggregation, createQueueLabel, and createQueueJsonSchema. It is direct and unambiguous, though it does not explain what a queue is or when it should be used.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives such as updateQueue, deleteQueue, or listQueues. It also omits important contextual conditions like the automation migration requirement mentioned in the automation_id parameter description. An agent receives no direction for choosing this tool correctly.

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

createQueueAggregationCreate Queue AggregationBInspect

Create an immutable aggregation definition on a queue.

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier
definitionYes
maximum_stale_age_secondsNo

TDQS

B3.4/5.0
Behavior3/5

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

The word 'immutable' adds useful behavioral context beyond the annotations, signaling that a created aggregation definition cannot later be modified in-place. However, the description does not mention side effects, permissions, what happens if the queue does not exist, or whether creation replaces any existing definition.

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

Conciseness4/5

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

The description is a single front-loaded sentence with no filler or repetition. It is appropriately concise for stating the core action, though it sacrifices useful detail that would require a second sentence, so it is not quite excellent.

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

Completeness2/5

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

For a tool with a highly complex nested input schema and no output schema, one short sentence is insufficient. Missing context includes parameter semantics, lifecycle implications of immutability, relationship to evaluateQueueAggregation/refreshQueueAggregation, and what a successful response looks like.

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

Parameters2/5

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

Schema description coverage is only 33%, so the description needed to compensate for the undocumented parameters, but it does not. It only says 'aggregation definition on a queue' and never explains maximum_stale_age_seconds or the meaning/structure of the definition object's measures, dimensions, filters, or timeDimension.

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 names a specific action ('Create') and a specific resource: an immutable aggregation definition on a queue. It is concise and distinguishable from sibling tools such as listQueueAggregations, evaluateQueueAggregation, and refreshQueueAggregation.

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

Usage Guidelines3/5

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

The description implies this tool is for creating a new aggregation definition, but it does not explicitly state when to use it versus related tools like evaluateQueueAggregation or refreshQueueAggregation. No exclusions, prerequisites, or alternative routing guidance are provided.

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

createQueueLabelCreate Queue LabelBInspect

Create a label on a queue without assigning it to a case.

NameRequiredDescriptionDefault
keyNo
valueYes
queue_idYesThe queue's unique identifier
color_hueNo

TDQS

B3.4/5.0
Behavior3/5

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

Annotations already indicate a write operation that is non-idempotent and non-destructive. The description adds the useful distinction that the label is not assigned to a case, but it does not disclose behavior like duplicate handling, idempotency implications, or required permissions. No contradiction with annotations.

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

Conciseness4/5

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

The description is a single efficient sentence with no wasted words. It front-loads the action and resource, though it is somewhat terse given the tool's parameter complexity.

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

Completeness2/5

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

For a tool with four parameters, low schema coverage, and no output schema, the description is too thin. It omits parameter semantics, return behavior, and any operational context, leaving the agent to infer too much.

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

Parameters2/5

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

Schema description coverage is only 25%, with queue_id documented. The description loosely implies queue_id and value (label text) but does not explain key or color_hue at all. With low schema coverage, the description was expected to compensate, and it largely does not.

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 uses a specific verb and resource: 'Create a label on a queue' and explicitly distinguishes it from case-level labeling. This clearly differentiates it from siblings like assignCaseLabels and aligns with the title.

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

Usage Guidelines3/5

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

The phrase 'without assigning it to a case' gives a partial routing signal, implying this is for queue-level labels rather than case labels. However, it does not explicitly name alternatives such as assignCaseLabels, updateQueueLabel, or listQueueLabels, nor state when to prefer this tool.

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

createRevisionCreate RevisionCInspect

Create a new revision for an existing agent.

NameRequiredDescriptionDefault
nameYesBuild name
configNoBuild configuration. An agent step takes the latest agent schema (legacy v1 agent configs are not accepted); a code step takes a code-step config. Omit it to get the step family's default first build.
agent_idYesThe agent's unique identifier
handover_toNoThe single agent or code step to run after this one completes ("Handover to"). Mutually exclusive with handover_target_ids.
source_build_idNoBuild ID to copy integrations and queue links from. A numbered revision copied this way is recorded as the new build's parent.
handover_optionsNoCode steps only. The targets the program may request, and whether it must. Null clears them; omit to inherit the source build's. Mutually exclusive with handover_to.
handover_target_idsNoAgent IDs that this agent can hand work off to, used exactly as sent; an empty list means none. Send null or omit it to use the agents the AOP mentions with <DUVO:AGENT> tags. Targets are never copied from the source build.
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

C2.9/5.0
Behavior2/5

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

Annotations already declare this as a non-read-only, non-idempotent, non-destructive local mutation, so the description should add operational context — but it adds none. It doesn't say whether the new revision is a draft or active, whether creating it affects live agent traffic, or what side effects (build creation, integration copying via source_build_id) occur. For a mutation on an automation pipeline, that is a real gap.

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

Conciseness4/5

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

One short, front-loaded sentence with no filler or repetition. It is efficient, though the brevity is under-specification rather than genuine density of information.

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

Completeness2/5

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

For a mutation tool with 8 parameters, a large nested config union (agent v2 vs code-step v1), no output schema, and a sibling set full of revision-related operations, a single sentence is insufficient. Key facts an agent needs — draft vs active state, required permissions, downstream promotion/publish steps, and whether config omission yields a default build — are all absent.

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 all 8 parameters — including the complex config union, source_build_id, and selected_automation_revision_id — are documented in the schema itself. The description contributes no additional parameter meaning, which matches the baseline-3 rule when the schema does the heavy lifting.

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

Purpose4/5

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

The description gives a specific verb and resource ("Create a new revision") scoped to "an existing agent," so the agent knows the target entity. It stops short of distinguishing this from nearby siblings such as createSkillRevision, generateRevision, updateRevision, or duplicateAgent.

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

Usage Guidelines2/5

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

There is no statement of when to use this versus generateRevision, duplicateAgent, or updateRevision, nor any prerequisite (e.g., does a revision require a source build, an automation revision, or a promotion step afterward?). Usage is only inferable from the name.

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

createSandboxCreate SandboxAInspect

Create a new sandbox for file uploads. The returned sandbox_id can be passed to POST /v2/teams/:team_id/runs to stage data for a run.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.3/5.0
Behavior3/5

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

Annotations already establish that this is not read-only, not idempotent, and not destructive. The description adds the useful downstream behavior that the returned sandbox_id is passed to a run endpoint, but it does not disclose other behavioral traits such as cleanup, persistence, or authorization requirements.

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

Conciseness5/5

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

Two sentences with no filler. The primary purpose is stated first, followed by the actionable downstream usage. Every sentence contributes meaningful information.

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 zero-parameter creation tool with no output schema, the description is complete: it names the resource, states what is returned (sandbox_id), and explains how to use it. An agent has enough information to call the tool and understand its role in the broader workflow.

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

Parameters4/5

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

The tool has zero parameters and schema coverage is 100%, so there is no parameter ambiguity. The description appropriately focuses on what the tool returns and how that return value is used.

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 clearly states the verb and resource: 'Create a new sandbox for file uploads.' It also explains the sandbox's role in staging data for a run, which distinguishes it from sibling tools like createSandboxUploadUrl or uploadSandboxFile.

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?

The description gives clear context for when to use the tool: when a sandbox is needed for file uploads before staging data for a run. It does not explicitly mention alternatives or when-not-to-use, but the downstream use case is specific enough to guide selection.

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

createSandboxUploadUrlCreate Sandbox Upload UrlAInspect

Get a presigned URL for uploading a file into a sandbox. Use for files larger than 10MB; smaller files can be uploaded directly via POST /v2/sandboxes/:sandbox_id/files.

NameRequiredDescriptionDefault
pathYesPath where the file will be uploaded (e.g. /workspace/data.csv)
sandbox_idYesThe sandbox's unique identifier

TDQS

A4.2/5.0
Behavior3/5

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

Annotations provide the safety profile (not read-only, not idempotent, not destructive), so the bar for additional disclosure is lower. The description adds the presigned-URL mechanism and the size threshold as useful behavioral context. However, it does not disclose URL expiration, whether the sandbox must already exist, or side effects of generating the URL. With annotations present, the added value is moderate but not rich — a 3 is appropriate.

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

Conciseness5/5

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

Two sentences with zero waste. The core function is front-loaded in the first sentence, and the second sentence earns its place by providing the routing decision. Every word contributes either to what the tool does or when to use it.

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

Completeness4/5

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

For a simple 2-param tool with fully documented schema and clear annotations, the description covers the essential calling decision: what it returns (a presigned URL), when to use it (files > 10MB), and its sandbox scope. Minor gaps remain: no output schema means the exact response shape is unspecified, and it doesn't explicitly differentiate from the generic createFileUploadUrl sibling — though the sandbox scoping largely handles that.

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% — both sandbox_id and path are already documented in the schema with meaningful descriptions. The tool description reinforces the upload context via the 10MB threshold, but adds no parameter-level syntax or format detail beyond the schema. Per calibration, baseline 3 applies when the schema does the heavy lifting.

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 states a specific verb and resource: 'Get a presigned URL for uploading a file into a sandbox.' The sandbox scoping and the presigned-URL mechanism clearly distinguish it from siblings like uploadSandboxFile (which performs the upload) and createFileUploadUrl (generic, non-sandbox URL). An agent can tell this tool apart from its nearest alternatives without opening their schemas.

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

Usage Guidelines5/5

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

The description explicitly names the decision rule for this tool: 'Use for files larger than 10MB; smaller files can be uploaded directly via POST /v2/sandboxes/:sandbox_id/files.' This is model usage guidance — it states when to use this tool, when not to, and provides the exact alternative endpoint. Nothing is left to inference.

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

createScheduleCreate ScheduleBInspect

Create a schedule for an agent. The schedule fires against the agent's live build. The authenticated user owns the schedule. On a team with revisions, a repeating schedule for an Agent in an automation joins that automation's revisions: one matching a schedule the automation already runs fires at once, and a new one is saved to the automation's draft and fires once the draft is made active (see pending_change).

NameRequiredDescriptionDefault
dayNo
cronNo
timeNo
enabledYes
agent_idYesThe agent's unique identifier
timezoneYes
frequencyYes
recurringNo
day_of_monthNo

TDQS

B3.3/5.0
Behavior4/5

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

Annotations already declare non-read-only, non-destructive, non-idempotent, so the safety profile is covered. The description adds genuinely useful behavior: the schedule targets the live build, ownership is implicit to the caller, and repeating schedules inside an automation either fire immediately (matching an existing schedule) or land in the draft and fire on activation — context an agent could not infer from the schema.

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

Conciseness4/5

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

Front-loaded with the core action, then the operationally important detail. The revision/draft sentence is long and niche, but it is conditioned ('On a team with revisions') rather than bloating the general case, so it largely earns its place.

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

Completeness2/5

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

For a 9-parameter mutation with 11% schema coverage and no output schema, the description should explain at minimum how frequency interacts with cron/day/time/day_of_month and what timezone format is expected. It covers the automation-revision behavior well but leaves the actual scheduling payload undefined.

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

Parameters2/5

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

Schema description coverage is only 11% across 9 parameters, so the schema carries almost no semantics for cron, time, day, day_of_month, frequency, recurring, or timezone. The description mentions no parameters at all (the referenced `pending_change` isn't even an input), leaving the caller with zero guidance on how frequency='custom' relates to cron vs. day/time.

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

Purpose4/5

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

States a specific verb and resource ('Create a schedule for an agent') and adds scope that matters: the schedule fires against the agent's live build and is owned by the authenticated user. It doesn't explicitly name updateSchedule/deleteSchedule as the alternatives, so it stops short of full sibling differentiation.

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

Usage Guidelines3/5

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

Gives real context for when the created schedule takes effect (live build; automation revisions join draft vs. immediate fire), which implicitly tells the agent when this tool is the right one. But there is no explicit 'use updateSchedule to modify an existing schedule' or exclusion guidance, so usage is inferred rather than stated.

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

createSecretCreate SecretAInspect

Create an env-var secret. Personal by default; pass shared: true to create a team-shared secret (requires lead builder role).

NameRequiredDescriptionDefault
nameYes
sharedNo
valuesYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
service_slugNo

TDQS

A4.1/5.0
Behavior4/5

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

The annotations already signal non-readonly, non-idempotent, non-destructive behavior. The description adds useful context beyond annotations: the default personal scope and the role requirement for shared secrets. This helps the agent anticipate authorization behavior.

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

Conciseness5/5

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

The description is two concise sentences with no filler. The core action is front-loaded, and the key parameter behavior (`shared: true` plus role requirement) is stated efficiently.

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

Completeness3/5

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

Given five parameters, low schema coverage, and no output schema, the description covers the main creation flow but leaves `service_slug` unexplained. It also does not mention what the tool returns, although the absence of an output schema lowers that burden. Overall, it is adequate for the common case but not fully complete for all parameters.

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 only 20%, so the description must compensate. It does clarify the `shared` parameter semantics and default behavior, and "env-var secret" implies the shape of `values`. However, it says nothing about `service_slug`, which remains undocumented in both schema and description.

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 states a specific verb and resource: "Create an env-var secret," which clearly identifies the operation and the object type. It also distinguishes personal vs. team-shared scope, helping the agent differentiate this from sibling tools like createCredential or updateSecret.

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?

The description gives clear context: personal is the default, and team-shared requires both `shared: true` and the lead builder role. It does not explicitly enumerate when to avoid this tool in favor of siblings, but the create operation and env-var type make the primary use case clear.

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

createSkillCreate SkillAInspect

Create or update a skill from a JSON body. The server constructs SKILL.md from the provided fields and stores it. If a skill with the same name already exists in the team, it is updated.

NameRequiredDescriptionDefault
nameYesSkill name. 1-64 lowercase alphanumeric chars and hyphens; no leading/trailing or consecutive hyphens.
contentYesMarkdown body of SKILL.md without YAML frontmatter. The server prepends the frontmatter from the other fields.
licenseNoOptional: license name or reference to a bundled license file.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
metadataNoOptional: arbitrary key-value metadata.
descriptionYes1-1024 chars describing what the skill does and when to invoke it.
allowed-toolsNoOptional (experimental): space-delimited list of pre-approved tools.
compatibilityNoOptional: 1-500 chars describing environment requirements.

TDQS

A3.5/5.0
Behavior4/5

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

The description discloses the key non-obvious side-effect: if a skill with the same name already exists in the team, it is updated, which implies possible overwriting of existing content. It also clarifies that the server generates SKILL.md from the provided fields, adding behavioral context beyond the annotations.

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

Conciseness5/5

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

The description is two sentences, front-loads the core action, and includes the important update behavior without filler. Every clause contributes useful information.

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

Completeness3/5

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

The description covers the essential create/update behavior and team-scoped name uniqueness, while the schema handles parameter documentation. However, with no output schema, the description does not say what the call returns, and it gives no indication of how this tool relates to the revision workflow represented by createSkillRevision and promoteSkillRevision.

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%, and the schema already documents name constraints, content behavior, team_id fallback rules, and optional fields. The description adds only the high-level 'JSON body' framing and SKILL.md construction, which is helpful but does not meaningfully expand parameter-level understanding.

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

Purpose4/5

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

The description uses a specific verb-resource pair ('Create or update a skill') and adds concrete behavior: the server constructs SKILL.md and stores it. It is clear, but it does not explicitly differentiate the tool from closely related siblings like createSkillRevision or updateSkillRevision, so it stops short of a 5.

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

Usage Guidelines2/5

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

No explicit when-to-use guidance is provided, and the description never mentions alternatives such as createSkillRevision, updateSkillRevision, or updateSkillFile. The only usage hint is the conditional update-on-same-name behavior, which describes behavior rather than telling the agent when to select this tool over its siblings.

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

createSkillRevisionCreate Skill RevisionA
Idempotent
Inspect

Open a draft revision of a skill, copying its files from the active revision (or from source_revision_id). Edit the draft with updateSkillRevisionFile and deleteSkillRevisionFile, then activate it with promoteSkillRevision — the previously active revision stays intact and can be re-activated later. A skill has at most one open draft: if one already exists this returns it with created: false.

NameRequiredDescriptionDefault
skill_idYesSkill ID.
source_revision_idNoRevision to fork the new draft from. Defaults to the live revision (or the skill's current files if there is no live revision yet).

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare non-read-only, non-destructive, idempotent behavior, so the description's job is additive context, which it delivers: the previously active revision is preserved and re-activatable, and a pre-existing draft is returned with created: false. This explains the idempotency mechanism concretely rather than just restating the hint.

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

Conciseness5/5

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

Three tight sentences, zero filler, and the core action is front-loaded. Each sentence adds a distinct fact: what is created, the editing/activation workflow, and the single-draft invariant.

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 mutation tool with annotations and no output schema, the description supplies everything an agent needs: the operation's effect, the follow-up tool chain, the safety guarantee for the existing revision, and the return-value edge case (created: false). Nothing material is missing.

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 coverage is 100%, so both parameters are already documented in the schema, including the default-fork behavior of source_revision_id. The description reinforces the fork semantics ('or from source_revision_id') but adds no syntax or format detail beyond the schema, making the baseline 3 appropriate.

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?

States a specific verb and resource ('Open a draft revision of a skill') and immediately defines the scope: files are copied from the active revision or from source_revision_id. It clearly differentiates itself from siblings by naming updateSkillRevisionFile, deleteSkillRevisionFile, and promoteSkillRevision as the operations that follow.

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

Usage Guidelines5/5

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

Explicitly lays out the workflow: create the draft here, edit with updateSkillRevisionFile/deleteSkillRevisionFile, then activate with promoteSkillRevision. It also states the reuse condition — 'at most one open draft' — giving the agent a clear rule for when calling this is redundant.

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

createTeamInviteCreate Team InviteAInspect

Invite one person to a team. Pass processId to invite them to a specific Clarity process instead of the whole team (that requires the team:clarity-member role). Creating the invitation does NOT email anyone — call sendTeamInviteEmail with the returned id to deliver it, or use bulkCreateTeamInvites, which creates and emails in one step.

NameRequiredDescriptionDefault
roleYesTeam role to grant. One of: team:owner, team:superadmin, team:admin (deprecated), team:manager, team:builder, team:member, team:clarity-member. You cannot grant a role above your own. Process invitations must use team:clarity-member.
emailYesEmail address of the person to invite.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
processIdNoInvite the person to this Clarity process rather than the whole team. Requires the team:clarity-member role.
process_role_idNoConfigured Process role to assign alongside the Clarity invitation. Requires processId; the role must belong to that Process.
interviewRequestedNoWhether to ask the person to record an interview about the process. Defaults to true. Pass false to give Clarity Member access to the process only; that requires processId and the clarity_invite_without_interview feature flag. Inviting someone already asked for an interview with false keeps the request.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false and openWorldHint=false, so the safety profile is structured. The description still adds a genuinely non-obvious behavioral trait: the invitation is created but no email is sent, plus the role-permission requirement for process invites. It does not cover error/idempotency edge cases beyond what annotations flag.

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

Conciseness5/5

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

Three sentences, front-loaded with the core action, then the scoping parameter, then the delivery workflow. Every sentence carries distinct, non-redundant information with no filler.

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

Completeness4/5

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

There is no output schema, so the description carries the return-value burden; it partially compensates by referencing 'the returned id', implying an id is returned, but does not describe the full response shape. For a 6-param mutation tool with full annotation coverage the essential calling guidance is present.

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 schema already documents role, team_id, processId, process_role_id and interviewRequested in detail. The description reinforces processId's semantics and the role coupling but adds little syntax or format meaning beyond the schema, so the baseline 3 applies.

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?

States a specific verb and resource ('Invite one person to a team') and immediately scopes the two variants (whole-team vs. process-level via processId). It names the sibling tools bulkCreateTeamInvites and sendTeamInviteEmail, so an agent can distinguish this from them without opening a schema.

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

Usage Guidelines5/5

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

Explicitly routes the agent: condition for processId (invite to a specific process, requires team:clarity-member), the fact that this tool does NOT deliver email, and the two follow-up alternatives (sendTeamInviteEmail with the returned id, or bulkCreateTeamInvites for one-step create-and-email). When-to-use and alternatives are both covered.

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

createWorkspaceCreate WorkspaceA
Idempotent
Inspect

Set up the user's Duvo workspace, or return the one they already have (created: false, nothing created). Call it first when the user has no workspace: other tools fail with 'User has no current team' until one exists. A new workspace is on the Free plan, with Clarity and Automation. has_clarity_access says whether the team's plan includes Clarity, interviews_remaining counts interviews left on the plan without subtracting people invited but not yet interviewed, and billing_url is where the user upgrades. If the user's organization or email domain is already on Duvo, the call is refused with a link the user must open.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.8/5.0
Behavior5/5

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

Annotations cover safety (readOnlyHint=false, idempotentHint=true, destructiveHint=false), and the description goes further by confirming idempotency semantics ('nothing created' on repeat), plus disclosing the refusal condition and the plan/tier outcome of a successful call. It adds real behavior beyond the structured fields.

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

Conciseness4/5

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

Front-loaded with the core action and the 'call it first' rule before any detail. The middle return-field list is dense but each field carries non-obvious meaning (e.g. `interviews_remaining` does not subtract invited-but-not-interviewed people), so it largely earns its space.

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?

There is no output schema, so the description correctly compensates by naming the returned fields and their semantics, and it covers prerequisites, idempotent behavior, and the refusal error path. Nothing an agent needs before invoking is missing.

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

Parameters4/5

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

The tool takes zero parameters, so the 4 baseline applies. The description instead documents return-side fields (`has_clarity_access`, `interviews_remaining`, `billing_url`), which is helpful but is not parameter semantics.

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?

States a specific verb and resource ('Set up the user's Duvo workspace') and immediately disambiguates the idempotent path ('or return the one they already have (`created: false`, nothing created)'). An agent can tell exactly what the tool produces without inspecting the schema.

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

Usage Guidelines5/5

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

Gives an explicit trigger ('Call it first when the user has no workspace') plus the concrete failure mode of skipping it ('other tools fail with User has no current team'). It also defines an exclusion path (refused when the org/email domain is already on Duvo). This is actionable routing guidance.

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

declineClarityLandscapeNodeDecline Clarity Landscape NodeA
Destructive
Inspect

Reject a proposed process landscape node while it is still a proposal, removing it and any proposed descendants. Real processes nested underneath survive and move back to Unsorted. Only proposals can be declined — an accepted node is removed with deleteClarityLandscapeNode.

NameRequiredDescriptionDefault
orgIdYes
nodeIdYesThe proposed node to reject.

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the destructiveHint=true annotation by spelling out the blast radius: the node and its proposed descendants are removed, while real processes beneath it survive and are moved back to Unsorted. That side-effect detail is exactly what an agent needs before invoking a destructive, non-idempotent mutation.

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

Conciseness5/5

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

Three sentences, front-loaded with the action and scope, then the side effect, then the sibling routing rule. Every sentence carries information an agent would otherwise have to guess.

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 two-parameter destructive mutation with no output schema, the description covers precondition, deletion scope, survivorship of nested processes, and the sibling alternative. The only untouched field is orgId, which is a minor gap against otherwise complete behavioral coverage.

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 coverage is 50%: nodeId is documented as 'The proposed node to reject' but orgId is undocumented anywhere. The description reinforces that the target is a proposal but adds no format, scope, or org-context detail, so it neither compensates for the gap nor falls below the baseline for low coverage.

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?

States a specific verb (reject/decline) and resource (a proposed process landscape node), and explicitly contrasts itself with deleteClarityLandscapeNode for accepted nodes. An agent can distinguish it from acceptClarityLandscapeNode and deleteClarityLandscapeNode without opening a schema.

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

Usage Guidelines5/5

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

Gives an explicit precondition ('while it is still a proposal'), an explicit exclusion ('only proposals can be declined'), and names the correct alternative for the other case (deleteClarityLandscapeNode). Nothing is left to inference.

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

declineRevisionGenerationDecline Revision GenerationA
Destructive
Inspect

Discard generated changes by restoring checkpoint_config and completing the builder run. The saved draft is not activated.

NameRequiredDescriptionDefault
build_idYesThe revision identifier.
builder_run_idYesThe builder run returned by generation or status, belonging to this revision.
expected_started_atYesCopy started_at from the status being reviewed. Each prompt has its own builder run ID; stale review identities return 409.

TDQS

A3.8/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true, idempotentHint=false and readOnlyHint=false. The description goes beyond them by naming exactly what is destroyed ('generated changes'), what is restored ('checkpoint_config'), and the resulting state ('the saved draft is not activated'), which is useful non-obvious side-effect detail.

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

Conciseness5/5

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

Two short sentences, zero waste, and the destructive action is front-loaded ahead of the resulting state.

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

Completeness4/5

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

For a 3-param destructive tool with no output schema, the description covers the mutation, its side effect and the end state. Minor gaps (concurrency/409 handling, idempotency) are covered by annotations and the schema instead.

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 build_id, builder_run_id and expected_started_at are fully documented in the schema, including the stale-identity 409 behavior. The description adds no parameter-level meaning beyond that, so the baseline 3 applies.

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

Purpose4/5

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

States a specific verb and resource ('Discard generated changes', 'completing the builder run') and the tool is clearly the negative counterpart to acceptRevisionGeneration. It stops short of naming the sibling, so the contrast must be inferred from 'Discard'.

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

Usage Guidelines3/5

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

Usage is implied by the contrast with acceptRevisionGeneration and the mention of a review being discarded, but there is no explicit when-to-use / when-not-to-use statement or alternative routing. The 409 precondition is only in the schema, not the description.

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

deleteAgentDelete AgentA
DestructiveIdempotent
Inspect

Delete an agent and cascade-clean its schedules, case triggers, builder runs, and handover targets. Any active jobs are interrupted and their sandboxes paused.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true and readOnlyHint=false, so the description adds purely additive value: it specifies exactly what gets destroyed (schedules, case triggers, builder runs, handover targets) and discloses runtime side effects (active jobs interrupted, sandboxes paused). This is precisely the behavioral context an agent needs beyond the annotation flags.

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

Conciseness5/5

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

Two dense sentences with zero waste. The core action and cascade scope are front-loaded in sentence one, and the side effects on active jobs and sandboxes follow in sentence two. Every clause earns its place.

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

Completeness4/5

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

For a destructive one-parameter tool, the combination of annotations (destructive, idempotent) and description (cascade scope, job interruption, sandbox pause) gives an agent nearly everything needed. With no output schema, return behavior is not specified, but the idempotentHint=true annotation partially covers the error/no-op question for already-deleted agents.

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% — the single agent_id parameter is already described as 'The agent's unique identifier' with a UUID format. The description adds no parameter-level meaning, so the baseline of 3 applies.

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?

States a specific verb and resource ('Delete an agent') and then details the full scope of what deletion entails via the cascade list. This distinguishes it clearly from partial-deletion siblings like deleteAgentCaseTrigger, deleteAgentFolder, deleteSchedule, and deleteAutomation.

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?

The context of use is clear: this is the whole-agent destruction path. The cascade-clean detail implicitly signals to an agent that if it only wants to remove a schedule, trigger, or run, a more targeted sibling should be used. However, no alternative is named explicitly and no when-not-to-use conditions are stated.

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

deleteAgentCaseTriggerDelete Agent Case TriggerA
DestructiveIdempotent
Inspect

Delete a case trigger. Only the trigger creator or a builder/admin can delete it.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier
trigger_idYesThe case trigger's unique identifier

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already mark the operation destructive and non-read-only; the description adds the authorization requirement, which annotations do not convey. No contradiction with idempotentHint is present.

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

Conciseness5/5

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

Two short sentences, front-loaded with the action; the permission note is the only additional information. No filler or repetition.

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

Completeness4/5

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

For a two-parameter delete with safety annotations already provided, the description covers the essential action and authorization context. It doesn't explicitly mention the agent-trigger ownership relationship, but that is strongly implied by the tool name and schema.

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?

Both parameters are fully described in the schema with UUID formats and meanings, so schema coverage is 100%. The description adds no parameter-specific details, matching the baseline for schema-covered parameters.

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 direct verb and object ('Delete a case trigger'), stating exactly what the tool does. The phrase 'case trigger' distinguishes it from sibling deletion tools such as deleteSlackTrigger, and the permission clause further narrows the operation's scope.

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?

The authorization constraint ('Only the trigger creator or a builder/admin can delete it') gives an agent clear context on when invocation is permitted. It does not name alternatives like updateAgentCaseTrigger, but for a delete tool this is sufficient context.

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

deleteAgentFolderDelete Agent FolderA
DestructiveIdempotent
Inspect

Delete an agent folder. If the folder contains assignments or subfolders, pass force=true to delete it and move the contained assignments to the root level.

NameRequiredDescriptionDefault
forceNoPass 'true' to delete a folder that still contains assignments or subfolders. Any contained assignments will be moved to the root level.
folder_idYesThe folder's unique identifier

TDQS

A4.7/5.0
Behavior4/5

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

The description discloses the destructive nature and the side effect of moving assignments when force is used. While annotations already indicate destructiveHint, the description adds context about the force condition. It does not contradict annotations, but could mention that without force the delete will fail on non-empty folders, which is implied.

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

Conciseness5/5

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

The description is concise, two sentences, with no redundant words. It efficiently conveys the core action and the conditional behavior.

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?

In the context of agent folder management, this description fully covers what the tool does and when to use force. It does not require additional explanation about return values or errors, as no output schema is expected.

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

Parameters4/5

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

The schema descriptions for both parameters are clear and match the tool description. The folder_id is described as a unique identifier, and force explains the condition and effect. The tool description repeats the force semantics but adds no new information beyond schema, which is sufficient.

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 clearly states the action (delete) and the resource (agent folder), and distinguishes it from sibling tools like createAgentFolder and updateAgentFolder. It also mentions the force option, making the purpose unambiguous.

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

Usage Guidelines5/5

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

It explicitly specifies when to use the force parameter ('If the folder contains assignments or subfolders') and describes the resulting behavior (moving assignments to root level). This provides clear guidance for correct invocation.

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

deleteAgentTriggerDelete Agent TriggerA
DestructiveIdempotent
Inspect

Permanently delete one of your own event triggers on an agent. The agent stops starting Runs for that event and the trigger's filter config is lost. To keep the trigger but stop it firing, upsert it with enabled: false instead.

NameRequiredDescriptionDefault
agentIdYesThe agent's unique identifier
triggerIdYesThe trigger to delete

TDQS

A4.7/5.0
Behavior5/5

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

The description fully discloses the permanent nature, the loss of filter config, and the immediate effect on Runs. It also aligns with the destructiveHint and idempotentHint annotations, going beyond them to explain specific side effects.

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

Conciseness5/5

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

The description is two sentences, direct and free of extraneous information. It packs essential details into a compact structure without sacrificing clarity.

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 simple delete operation with no output schema, the description covers the core action, consequences, and alternative. No additional context (e.g., error handling, prerequisites) is necessary for an agent to understand and invoke this tool correctly.

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?

Both parameters have clear descriptions in the schema (agentId as 'The agent's unique identifier' and triggerId as 'The trigger to delete'). The description adds no further parameter-specific detail, but the schema coverage is 100%, so the baseline of 3 is appropriate.

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 clearly states the action (permanently delete), the resource (event triggers on an agent), and the effect (stops starting Runs, filter config lost). It also distinguishes from the alternative of disabling via upsert, making the purpose unambiguous.

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

Usage Guidelines5/5

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

Provides explicit guidance on when to use this tool vs. the alternative: 'To keep the trigger but stop it firing, upsert it with `enabled: false` instead.' This directly tells the agent when not to use it, leaving no ambiguity.

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

deleteAllNotificationsDelete All NotificationsA
DestructiveIdempotent
Inspect

Soft-delete all notifications for the authenticated user's current team, read or unread. Returns the count of notifications that were deleted. Destructive — only call on explicit user request, never bulk-delete unprompted. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.5/5.0
Behavior5/5

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

Goes beyond the destructiveHint annotation by explaining that deletion is soft, that the call returns the deleted count, and that a disabled feature yields 404. These details give an agent accurate expectations about side effects and failure modes.

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

Conciseness5/5

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

Three tightly scoped sentences lead with the action and scope, then cover return value, safety rule, and error condition. No filler or repetition of schema content.

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 destructive bulk operation with a single optional parameter, the description covers scope, return value, when it is permitted, feature requirements, and failure behavior. There is no output schema, but the description states what is returned, so an agent has enough to invoke it correctly.

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?

The schema already documents the single team_id parameter completely, so the description adds no extra parameter semantics. With 100% schema coverage, the baseline of 3 is appropriate because the description doesn't need to compensate.

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?

States a specific verb ('soft-delete'), a precise resource ('all notifications ... read or unread'), and a scope ('authenticated user's current team'). It also distinguishes itself from sibling deleteReadNotifications by explicitly covering both read and unread notifications.

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?

Provides clear usage context: only on explicit user request and never unprompted, plus the Notification Center feature prerequisite and 404 behavior. It does not name an alternative tool such as deleteReadNotifications for the read-only case, so it stops short of full alternative routing.

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

deleteAutomationDelete AutomationA
DestructiveIdempotent
Inspect

Soft-delete an automation. Its member agents and queues stop dispatching and disappear from listings, but their underlying rows and run history are preserved (not erased). Runs still in progress on its agents are interrupted.

NameRequiredDescriptionDefault
automation_idYesAutomation ID

TDQS

A4/5.0
Behavior5/5

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

Goes well beyond the annotations: it explains that this is a soft delete, that member agents and queues stop dispatching and vanish from listings, that underlying rows and run history are preserved rather than erased, and that in-progress runs are interrupted. That is exactly the destructive-scope detail an agent needs before invoking a destructiveHint=true tool, and it is fully consistent with the annotations.

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

Conciseness5/5

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

Three short sentences, each earning its place: the action front-loaded, then the visibility/dispatch effects, then the data-preservation and run-interruption caveats. No filler or restatement of the title.

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

Completeness4/5

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

For a single-parameter mutation with annotations covering destructiveness, idempotency and open-world scope, and with no output schema, the description supplies nearly everything needed. The only gap is post-delete behavior an agent might wonder about, such as whether the automation can be restored or what a repeat call returns.

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?

Only one parameter (automation_id) with 100% schema description coverage, so the schema already carries the semantics. The description adds no information about where the ID comes from (e.g., listAutomations) or what happens with an invalid or already-deleted ID, so the baseline 3 applies.

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

Purpose4/5

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

States a specific verb and resource ('Soft-delete an automation'), and the qualifier 'soft-' meaningfully distinguishes it from hard-delete siblings like deleteAgent or deleteQueue. Sibling differentiation is implicit through the resource name rather than stated explicitly, and no alternative tool (e.g., updateAutomation to disable) is referenced.

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

Usage Guidelines3/5

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

There is no explicit when-to-use or when-not-to-use guidance, and no named alternative such as updateAutomation or deleteAgent for adjacent cleanup tasks. Usage is only implied by the described consequences (listings disappear, runs interrupted), which a careful agent can infer from but which falls short of routing guidance.

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

deleteCaseDelete CaseA
DestructiveIdempotent
Inspect

Delete a case. Interrupts any associated active runs first.

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already mark the tool as destructive and idempotent. The description adds valuable context by disclosing that active runs are interrupted before deletion, which is not inferable from the annotations alone.

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

Conciseness5/5

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

Two short sentences: the action is first, and the key behavioral caveat is included without excess. Every part earns its place.

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 simple single-parameter destructive operation, the description is complete. Annotations cover idempotency and destructive intent, and the description covers the main side effect.

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?

The input schema fully documents the single case_id parameter with type, format, and description. The tool description adds no additional parameter detail, so it does not need to compensate.

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?

States a specific verb and resource: 'Delete a case.' The addition that it interrupts active runs first further distinguishes it from simple delete operations and clarifies scope.

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

Usage Guidelines3/5

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

The intended use is implied: use this when a case should be permanently removed. It does not explicitly compare against alternatives like updating a case or stopping runs, though the interruption note hints at related workflows.

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

deleteCaseAttachmentDelete Case AttachmentA
DestructiveIdempotent
Inspect

Remove a file from a case. The row is soft-deleted; deletion of the stored object is attempted best-effort.

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier
queue_idYesThe queue's unique identifier
attachment_idYesThe attachment's unique identifier

TDQS

A3.7/5.0
Behavior5/5

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

Adds important behavioral detail beyond the annotations by disclosing that the database row is soft-deleted and that the stored object deletion is best-effort. This sets accurate expectations about reversibility and failure modes.

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

Conciseness5/5

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

Two tight sentences with the primary action front-loaded and the critical side-effect immediately after. No filler, repetition, or unnecessary detail.

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

Completeness4/5

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

For a destructive tool with no output schema, the description covers the essential behavior: soft deletion and best-effort object removal. It could add permission or error details, but the annotations already cover idempotency and destructiveness, so nothing critical is missing.

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?

The input schema already provides 100% coverage of all three UUID parameters with descriptions. The tool description adds no per-parameter semantics, so the baseline of 3 applies.

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

Purpose4/5

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

States a specific verb and resource: 'Remove a file from a case.' This clearly matches the tool name and distinguishes it from generic deleteCase or deleteFile operations, though it does not explicitly contrast with sibling attachment tools.

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

Usage Guidelines2/5

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

No explicit guidance on when to use this tool versus alternatives such as finalizeCaseAttachment, getCaseAttachmentDownloadUrl, or deleteFile. The intended usage is only implied by the name and the 'from a case' scope.

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

deleteCaseQueueEvalRubricDelete Case Queue Eval RubricA
DestructiveIdempotent
Inspect

Remove a single case-level evaluation rubric. Cases settled after this are no longer judged against it; already-judged cases keep their original verdicts. Removing the queue's last remaining rubric is refused with 409 — whole-case evaluation regenerates rubrics for an empty set at the next settlement, so the removal would not stay removed.

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier
rubric_idYesThe case-level rubric's unique identifier

TDQS

A4.3/5.0
Behavior5/5

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

Even though destructiveHint and idempotentHint already flag safety, the description reveals substantive behavior beyond annotations: settled cases retain verdicts, future cases stop being judged, and the 409 refusal is explained with a rationale. This is exactly the kind of context an agent needs for a destructive deletion.

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

Conciseness5/5

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

Three sentences carry action, consequence, and edge case with no filler. The most important information is front-loaded, and the 409 exception is explained rather than merely stated.

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 destructive mutation with no output schema, the description covers what happens to future and already-judged cases, the edge case that triggers refusal, and why that refusal exists. Nothing essential for calling or understanding the outcome is missing.

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%, and the schema already defines queue_id and rubric_id as unique identifiers. The description adds mild context by tying rubric_id to a single case-level rubric and queue_id to the queue's last-remaining-rubric check, but it does not materially extend the schema's parameter semantics.

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 first sentence 'Remove a single case-level evaluation rubric' specifies the action, object, and scope precisely. The queue context and the single-rubric constraint separate it from generic deleteEvalRubric and from create/update/replace siblings.

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

Usage Guidelines3/5

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

The description conveys when deletion applies through 'single' and the queue context, and it gives a concrete exclusion: removal of the last remaining rubric is refused. However, it never names alternative tools such as updateCaseQueueEvalRubric or replaceCaseQueueEvalRubrics, so the when-vs-alternatives guidance is only implied.

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

deleteClarityArtifactChatConversationDelete Clarity Artifact Chat ConversationA
DestructiveIdempotent
Inspect

Soft-delete an open or running artifact-chat conversation for the current user.

NameRequiredDescriptionDefault
process_idYesThe Clarity process id
conversation_idYesThe artifact-chat conversation id

TDQS

A4/5.0
Behavior4/5

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

The annotations already flag destructive=true, but the description adds meaningful behavioral context: the deletion is a 'soft-delete' rather than a hard purge, and it is scoped to the current user. It also conditions validity on the conversation being 'open or running.' Nothing contradicts the annotations.

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

Conciseness5/5

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

One sentence, front-loaded with the operative verb, and no filler or repetition of the title. Every phrase ('soft-delete', 'open or running', 'current user') adds useful information.

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

Completeness4/5

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

For a simple two-parameter destructive action, the description provides the target, operation type, state precondition, and user scope; the schema covers parameter specifics. It does not describe return values or observable effects of a soft-delete, but with destructive and idempotent annotations this is a minor gap.

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?

The input schema documents both parameters fully with format, pattern, and descriptions, so the 100% coverage baseline applies. The tool description adds no additional meaning about process_id or conversation_id beyond what the schema already provides.

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 names the exact verb ('soft-delete'), the resource ('artifact-chat conversation'), and the relevant qualifiers ('open or running', 'for the current user'). This clearly distinguishes it from other delete and artifact-chat tools without requiring inspection of the schema.

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

Usage Guidelines3/5

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

The description makes the valid state ('open or running') and user scope explicit, so an agent can infer when it applies. However, it does not name the closely related alternative stopClarityArtifactChatConversation or explain when to choose this delete operation over stopping a conversation.

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

deleteClarityCaptureDelete Clarity CaptureC
DestructiveIdempotent
Inspect

Delete a capture from a clarity process

NameRequiredDescriptionDefault
idYesThe clarity process ID
captureIdYesThe capture ID to delete

TDQS

C2.9/5.0
Behavior2/5

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

The annotations already carry destructiveHint=true, readOnlyHint=false, and idempotentHint=true. The description adds no behavioral context beyond what the annotations already signal — it doesn't mention permanence, side effects, cascading deletions, or return behavior.

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

Conciseness4/5

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

The description is a single clear sentence with no wasted words. It is concise and front-loaded, though it could add a short clause about permanence or side effects without becoming bloated.

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

Completeness3/5

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

The tool is simple (2 params, no output schema), but the description omits consequences of deletion, such as whether it is permanent or whether dependent data is affected. The annotations cover the destructive nature, making this minimally sufficient but not complete for an agent that needs to anticipate side effects.

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%, with both id and captureId fully documented as UUIDs with clear meanings ('The clarity process ID', 'The capture ID to delete'). The description adds no additional parameter meaning, so baseline 3 applies.

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

Purpose4/5

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

The description states a specific verb and resource: 'Delete a capture from a clarity process.' This distinguishes it from sibling tools like deleteClarityProcess or deleteClarityFolder, though it doesn't clarify what a 'capture' is or how it differs from a 'suggestion' in sibling tools like dismissClarityCaptureSuggestion.

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

Usage Guidelines2/5

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

There is no guidance on when to use this tool versus alternatives such as getClarityCapture, listClarityLandscapeCaptures, or dismissClarityCaptureSuggestion. No prerequisites, exclusions, or context are provided to help an agent choose this tool correctly.

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

deleteClarityFolderDelete Clarity FolderA
DestructiveIdempotent
Inspect

Delete a process folder. Contained processes fall back to Unfiled.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
folderIdYesFolder to delete.

TDQS

A4.1/5.0
Behavior4/5

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

The annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=true. The description adds the key non-obvious behavior that contained processes are not destroyed but reassigned to Unfiled, which is valuable beyond the structured fields.

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

Conciseness5/5

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

Two short sentences with no repetition of the title or redundant qualifiers. The action is front-loaded and the side effect is stated in the second sentence, earning its place.

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 simple destructive tool with complete schema coverage, strong annotations, and no output schema, the description provides the critical behavioral consequence (processes fall back to Unfiled). Nothing needed for correct invocation is missing.

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%, with team_id already documented in detail and folderId described as 'Folder to delete.' The tool description adds no parameter-level meaning beyond what the schema provides, so the baseline of 3 is appropriate.

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 states a specific action ('Delete') and a specific resource ('a process folder'), and the second sentence clarifies scope by distinguishing folder deletion from process deletion. It differentiates this from siblings like deleteClarityProcess and updateClarityFolder without needing to open their schemas.

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

Usage Guidelines3/5

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

Usage is implied: use this when the goal is to remove a process folder. The fallback-to-Unfiled side effect gives useful context for choosing this over deleting processes individually, but no explicit when/when-not conditions or alternative tools are named.

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

deleteClarityLandscapeNodeDelete Clarity Landscape NodeA
DestructiveIdempotent
Inspect

Soft-delete a tree node and its descendants. Organization admins may delete any subtree; team managers may delete a childless process node owned by their team. The targeted node's linked clarity process and captures are deleted, while nested processes detach to the Unsorted bag.

NameRequiredDescriptionDefault
orgIdYes
nodeIdYes

TDQS

A4.5/5.0
Behavior5/5

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

The description discloses key behavioral traits beyond annotations: it is a soft-delete, it deletes linked clarity process and captures, and nested processes detach to the Unsorted bag. These side effects are critical for the agent to understand the impact. This goes well beyond the destructiveHint annotation and provides specific consequences.

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

Conciseness5/5

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

The description is two sentences, front-loaded with the main action and followed by essential details. No filler or redundancy. It efficiently covers the core behavior and conditions.

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 destructive operation with cascading effects, the description covers permissions, the scope of deletion, and the fate of linked and nested entities. It is complete enough for an agent to understand the consequences and prerequisites. The absence of an output schema is acceptable, and the description does not omit critical information.

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 coverage is 0%, so the description must explain parameter meaning. It explicitly identifies nodeId as the tree node being deleted, but orgId is not directly defined; its role is implied by 'Organization admins.' This partial clarification is insufficient for full compensation, though the context helps infer orgId's purpose.

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 clearly states the tool's function: soft-deleting a tree node and its descendants. It distinguishes this from other delete operations by specifying the scope (subtree vs childless) and the cascading effects on linked processes and captures. The name and description align, and it's unambiguous what resource is acted upon.

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?

The description provides explicit conditions for usage: organization admins can delete any subtree, while team managers can delete childless process nodes owned by their team. This gives clear permission-based guidance. However, it does not explicitly name alternative tools (e.g., deleteClarityProcess) or state when to choose this over others, though the distinction is implicit.

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

deleteClarityLandscapeNodeInterviewDelete Clarity Landscape Node InterviewB
DestructiveIdempotent
Inspect

Delete an organization-scoped folder interview

NameRequiredDescriptionDefault
orgIdYesThe organization ID
nodeIdYesThe clarity process folder node ID
interviewIdYesThe folder interview ID

TDQS

B3.3/5.0
Behavior3/5

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

Annotations already establish destructiveHint=true and idempotentHint=true; the description adds the scoped target and implies the interview is removed rather than the folder/node, but it does not disclose permanence, cascading effects, or permission requirements. There is no contradiction with the annotations.

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

Conciseness5/5

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

A single front-loaded sentence with no filler. It efficiently states the action and the resource, and every word contributes to the meaning.

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

Completeness3/5

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

For a simple three-ID delete, the schema and annotations supply most invocation details, and there is no output schema to explain. However, the description omits usage context such as which sibling delete tools it should be chosen over and what side effects, if any, occur, so it is only minimally complete.

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% and each parameter has a clear description, so the schema carries the parameter meaning. The tool description adds little beyond the 'organization-scoped' phrasing, which maps loosely to orgId, so baseline 3 is appropriate.

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

Purpose4/5

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

The description states a concrete verb ('Delete') and a specific resource ('organization-scoped folder interview'), so an agent can see this removes a folder/node-level interview. It is clear, but it relies on the title and sibling names to disambiguate from deleteClarityOrganizationInterview and deleteClarityTeamInterview, so it does not earn a 5.

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

Usage Guidelines2/5

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

The description gives no conditions, prerequisites, or exclusions, and never mentions the alternative interview-deletion tools. An agent has to infer when this tool is the right one from the tool name and sibling list.

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

deleteClarityOrganizationInterviewDelete Clarity Organization InterviewC
DestructiveIdempotent
Inspect

Delete an organization-level Clarity interview

NameRequiredDescriptionDefault
orgIdYes
interviewIdYesThe organization interview ID

TDQS

C2.6/5.0
Behavior2/5

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

The annotations already supply destructiveHint=true, idempotentHint=true, and readOnlyHint=false, and the description is consistent with them, so there is no contradiction. However, the description adds no behavioral context beyond the structured hints — it does not say whether deletion cascades to related artifacts, is permanent or recoverable, or affects associated data.

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

Conciseness3/5

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

The single sentence has zero wasted words and front-loads the action verb. But it is essentially a paraphrase of the tool title, so the brevity reflects under-specification rather than deliberate compression of rich content.

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

Completeness2/5

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

For a destructive tool with no output schema and only 50% parameter coverage, the description is too thin to support safe autonomous invocation. Missing are the effect of deletion (permanent vs. reversible), any cascade or scoping behavior, and the meaning of the orgId parameter — all of which an agent needs to invoke this correctly.

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

Parameters2/5

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

Schema description coverage is only 50%: interviewId has a minimal description ('The organization interview ID') while orgId is entirely undocumented in the schema. The tool description compensates for neither — it contains no information about the parameters, their relationship, or how an agent should obtain valid UUIDs for them.

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

Purpose4/5

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

The description states a specific verb ('Delete') and a scoped resource ('organization-level Clarity interview'), and the 'organization-level' qualifier helps differentiate it from the sibling tools deleteClarityTeamInterview and deleteClarityLandscapeNodeInterview. However, it adds nothing beyond the title and does not explicitly name or contrast those alternatives.

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

Usage Guidelines2/5

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

No guidance is provided on when to use this tool versus alternatives such as deleteClarityTeamInterview or deleteClarityLandscapeNodeInterview, nor any preconditions, side-effect warnings, or when-not-to-use conditions. The 'organization-level' scope only weakly implies a selection rule, and no exclusions or sibling references are present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteClarityProcessDelete Clarity ProcessA
DestructiveIdempotent
Inspect

Delete a Clarity process. The creator or a team admin can delete it unless capture analysis is still in progress, or a Module runs it — a Module's process is part of the Module, so the Module has to be removed first. An automation built from the process keeps running, with its setup answers and people, but is no longer linked to it.

NameRequiredDescriptionDefault
idYesClarity process id

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond annotations: names permission requirements, blocking conditions (capture analysis, Module ownership), and post-deletion behavior of derived automations (keeps running, setup answers and people retained, unlinked). This is rich operational context that annotations only hint at via destructiveHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core action, then permissions/exclusions, then side-effect behavior. Every sentence carries distinct information with no redundancy.

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 single-parameter destructive operation with no output schema, the description covers who can call, when deletion is blocked, how to unblock (remove Module first), and what happens to dependent automations. Complete.

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 coverage is 100% and only one parameter 'id' with format uuid. Description doesn't add semantics to the id beyond what schema provides. Baseline 3 appropriate.

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?

States a specific verb 'Delete' and resource 'Clarity process', and names side effects (automation unlinking) and constraints. Clearly distinguishes from siblings like deleteClarityProcessInviteLink or deleteClarityProcessLabel by focusing on the process itself.

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?

Explicitly states who can delete (creator or team admin) and when deletion is blocked (capture analysis in progress, or Module-owned process). No mention of alternatives like archive/duplicate, but the preconditions are clearly enumerated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteClarityProcessLabelDelete Clarity Process LabelB
DestructiveIdempotent
Inspect

Delete process tags from an organization.

NameRequiredDescriptionDefault
orgIdYes
labelIdYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=true, and the description's 'Delete' is consistent with them. It adds no extra behavior such as whether the tag is also removed from existing processes or whether deletion is permanent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single direct sentence with no filler, and the action is front-loaded. It is concise, though it achieves brevity at the expense of helpful context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-UUID deletion, the schema and annotations cover the mechanics, but the description leaves open what happens to labels attached to processes and gives no indication of return behavior. It is minimally viable but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not explain the meaning or relationship of orgId and labelId beyond the parameter names. It relies on the self-evident names and UUID format rather than adding semantic value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the verb ('Delete') and the resource ('process tags'), and scopes it to an organization. It does not contrast with the similar sibling unlinkClarityProcessLabels, so an agent cannot immediately tell whether this removes the label definition or just detaches it from a process.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided about when to call this tool instead of related tools such as unlinkClarityProcessLabels or assignClarityProcessLabels. The agent must infer usage from the name and sibling list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteClarityTeamInterviewDelete Clarity Team InterviewA
DestructiveIdempotent
Inspect

Delete a team-level Clarity interview

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
interviewIdYesThe team interview ID

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered without the description. The description adds no behavioral context beyond the operation itself — no mention of irreversibility, cascading effects on associated data, or auth requirements. It does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single seven-word sentence with zero filler. The core verb and scoping qualifier are front-loaded, and every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive operation with no output schema, the combination is adequate but thin: annotations flag destructiveness, and the schema fully documents parameters. However, the description does not state what happens to the interview's associated data or whether deletion is reversible, which would matter to an agent weighing side effects.

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%, and the schema already documents both parameters richly — especially team_id, which explains the API-key pinning vs OAuth multi-team behavior in detail. The description adds no parameter-level information, but at full schema coverage the baseline of 3 applies.

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 uses a specific verb ('Delete') and a precise resource ('team-level Clarity interview'). The 'team-level' qualifier effectively distinguishes it from sibling tools like deleteClarityOrganizationInterview and deleteClarityLandscapeNodeInterview, so an agent can tell them apart without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'team-level' scope implies when the tool applies, giving a basic sense of usage context. However, no alternatives are named and no exclusions or prerequisites (e.g., required permissions, inability to delete org-level interviews) are stated, leaving the agent to infer the boundary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteConnectionDelete ConnectionA
DestructiveIdempotent
Inspect

Delete a connection (disconnects the user's connection and removes any triggers bound to it).

NameRequiredDescriptionDefault
connection_idYesConnection ID

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (destructive, idempotent), the description adds that it disconnects the user's connection and removes any triggers bound to it. This provides valuable side-effect information not captured in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no unnecessary words. It efficiently communicates the operation and its side effects.

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 simple delete operation with no output schema, the description adequately explains what the operation does. It covers the essential behavior and side effects, making it complete for an agent to use.

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?

The single parameter connection_id has a clear description in the schema ('Connection ID'). The description does not add any additional meaning beyond what the schema already provides, so it meets the baseline for full schema coverage.

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 states a specific verb ('Delete') and resource ('connection'), and clarifies that it disconnects the connection and removes triggers. This clearly distinguishes it from other connection operations like updateConnection or getConnection.

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?

The description implies usage when you want to remove a connection entirely, but does not explicitly contrast with updateConnection or other alternatives. It lacks an explicit 'when-not' statement, but the context is strong enough to infer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteCredentialDelete credential by idA
DestructiveIdempotent
Inspect

Delete a login by id. Deleting a team-shared login requires lead builder role.

NameRequiredDescriptionDefault
idYes
userIdYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (destructiveHint=true, readOnlyHint=false), the description adds that deleting a team-shared login requires the lead builder role, which is useful authorization context. It does not elaborate on side effects, but the destructive hint already covers the core safety trait and the idempotent hint signals repeatability.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler: the core action comes first and the authorization caveat second. Every clause carries information that an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation with no output schema, the description plus annotations cover the key facts: what is deleted, by id, and the special role requirement. However, it leaves the required userId unexplained and does not mention whether deletion affects related revisions or integrations, so an agent may still need to infer ownership semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only the optional team_id has a schema description; the required id and userId are undocumented, and the description only says 'by id' without explaining what userId represents or how it relates to ownership. With schema description coverage at 33%, the description needed to compensate for the missing parameter context and did not.

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 states a specific action and target — 'Delete a login by id' — and the verb clearly distinguishes it from get/update/list credential tools. The term 'login' identifies the credential resource, and the title reinforces the same intent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The only usage signal is the role requirement for team-shared logins; there is no guidance on when to use deleteCredential versus deleteSecret or deleteConnection, nor any mention of how to find the id or what preconditions apply beyond role. The intended use is implied by the delete verb but not explicitly framed against alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteCustomIntegrationDelete Custom IntegrationA
DestructiveIdempotent
Inspect

Delete a custom integration type (team-level catalog entry) and cascade-remove related connections. Requires manager-or-above role.

NameRequiredDescriptionDefault
custom_integration_idYesCustom integration type ID

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description reveals an important behavioral consequence (cascade-removes related connections) and a role gate, which is beyond the annotations. However, it does not explicitly state irreversibility or idempotency, though the annotations already indicate destructive and idempotent hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with no extraneous information. The action, object, scope, effect, and requirement are all presented clearly and efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the key contextual elements (what is deleted, cascade effect, required role). It does not mention error scenarios or return values, but given the simplicity of the operation and lack of output schema, it is sufficiently complete for an agent.

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?

The schema description for 'custom_integration_id' fully covers the parameter meaning ('Custom integration type ID'). The tool description adds no additional context for this parameter, so it stays at the baseline for high schema coverage.

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 states a specific verb ('Delete'), the resource ('custom integration type'), and the scope ('team-level catalog entry'), along with the cascade effect on related connections. This clearly distinguishes the tool's purpose from other operations.

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?

The description includes a usage precondition ('Requires manager-or-above role') and the cascade behavior, but does not explicitly contrast with alternatives (e.g., soft delete or disable). The role requirement and effect provide some guidance, though not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteEvalRubricDelete Eval RubricA
DestructiveIdempotent
Inspect

Remove a single Agent-specific evaluation rubric. Future Runs on the build are no longer scored against it.

NameRequiredDescriptionDefault
agentIdYesThe agent's unique identifier (Assignment ID)
rubricIdYesThe custom rubric's unique identifier
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark destructiveHint=true, and the description adds the useful behavioral context that the rubric will no longer be used to score future Runs on the build. This clarifies the long-term effect of the destructive operation and does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two compact sentences with no wasted words. The primary action is front-loaded, and the consequence is stated immediately after, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a straightforward delete operation, the description adequately states the action and the lasting effect on future Runs. There is no output schema, but the annotations cover the destructive and idempotent profile, and the schema fully describes the optional revision parameter. The description is sufficient without over-explaining.

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?

The schema has 100% description coverage for all three parameters, so the baseline applies. The description's phrase 'Agent-specific' loosely aligns with agentId but adds no new meaning beyond what the schema already documents for agentId, rubricId, and selected_automation_revision_id.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Remove') and a specific resource ('a single Agent-specific evaluation rubric'), and it conveys the consequence of the action. The word 'single' helps separate it from bulk operations like replaceEvalRubrics, but it never explicitly names sibling tools, so differentiation is left partly to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a purpose (stop scoring future runs against a rubric) but provides no explicit when-to-use guidance, no exclusions, and no mention of alternatives such as updateEvalRubric, replaceEvalRubrics, or deleteCaseQueueEvalRubric. An agent is not told how to choose this tool over its siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteFileDelete FileA
DestructiveIdempotent
Inspect

Delete a file from team storage.

NameRequiredDescriptionDefault
pathYesPath of the file to delete relative to the team's storage root
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so the description doesn't need to repeat those. It does usefully specify that the path is relative to the team storage root, and the team_id param description adds important context about API key pinning. However, it doesn't describe post-delete behavior (e.g., whether it's permanent or reversible).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste. All critical information (action, resource, context) is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The operation is simple with a clear schema, destructive/readOnly annotations, and full parameter documentation. The main missing piece is whether deletion is permanent and whether it affects shared files — but for a simple delete operation this is a minor gap.

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 schema already documents both parameters. The description adds minimal semantic value beyond what the schema provides — the main contribution is the 'team storage root' context in the purpose statement.

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 states a specific verb ('Delete') and resource ('a file from team storage'), which clearly identifies the operation and distinguishes it from siblings like renameFile, getFileContent, and getFileDownloadUrl.

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?

The description makes the operation context clear ('team storage'), but doesn't explicitly name alternatives or state when not to use it. Sibling names like renameFile and getFileDownloadUrl provide implicit contrast, though the description itself doesn't mention them.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deletePulseDashboardDelete Pulse DashboardA
DestructiveIdempotent
Inspect

Delete a Duvo Pulse dashboard. Only the creator can delete it.

NameRequiredDescriptionDefault
artifactIdYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description transparently states that only the creator can delete, aligning with the destructiveHint annotation. It doesn't mention side effects like permanent deletion or cascading behavior, but the annotation already covers destructiveness, so no contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one concise sentence that conveys the essential information without any filler. It efficiently states both the action and the key constraint.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides enough context for a delete operation, including the permission model. It doesn't mention return values, but since there is no output schema, the description could optionally note success behavior. The missing info is minor for a delete action.

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?

The schema fully describes artifactId as a UUID with format and pattern, giving 100% coverage. The description adds no additional meaning beyond the parameter name, so the baseline score of 3 is appropriate.

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 clearly states the action ('Delete') and the target resource ('Duvo Pulse dashboard'), with a specific permission constraint. It unambiguously differentiates from other delete tools by naming the object type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus other delete tools (e.g., deleteCase, deleteAgent). It only mentions a permission restriction, but lacks context about prerequisites, alternatives, or when NOT to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deletePulseDashboardCommentDelete Pulse Dashboard CommentA
DestructiveIdempotent
Inspect

Delete a comment or reply on a Duvo Pulse dashboard. Allowed for the comment's author and for the dashboard's creator. Deleting a thread root keeps its replies, rendered under a deleted opening comment.

NameRequiredDescriptionDefault
commentIdYes
artifactIdYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses beyond annotations the non-obvious behavior that deleting a thread root preserves replies, and states permission restrictions. Annotations already indicate destructiveness and idempotency, but the description adds valuable edge-case information.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, using two sentences to convey the action, permissions, and special behavior. No redundant or extraneous information, and the structure is clear and well-organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple delete operation, the description provides sufficient context: what is deleted, who is allowed, and the outcome for thread roots. It does not explain return values or error handling, but these are less critical for a destructive tool. The main gap is the lack of parameter clarity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the description does not explicitly define the parameters. While commentId and artifactId can be inferred from context (comment and dashboard), the lack of explicit mapping or explanation leaves room for ambiguity, especially for artifactId.

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?

Clearly states the action (Delete), the resource (comment or reply on a Pulse dashboard), and distinguishes from sibling tools like deletePulseDashboard. Includes permission details and the special behavior for thread roots, making the purpose unambiguous.

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?

Provides usage context by specifying the permission requirements (author or dashboard creator) and the effect on thread replies. Does not explicitly reference alternative tools or when not to use, but the description is sufficient for an agent to select this tool for comment deletion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteQueueDelete QueueA
DestructiveIdempotent
Inspect

Delete a queue. Interrupts all associated active runs first and returns the number of deleted cases plus the IDs of runs that were stopped.

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description explicitly discloses two key behavioral aspects: that active runs are interrupted first and that the response includes the number of deleted cases and IDs of stopped runs. This goes beyond the annotations (which already indicate destructive and idempotent behavior) to provide concrete details about side effects and return values, giving full transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the primary action and succinctly adds the important details about interruption and return values. It is concise without omitting critical information.

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?

Given the simplicity of the operation, the description provides sufficient context: it states what it does, the side effect on runs, and what it returns. There is no output schema, but the description covers the return contents. This is complete for an agent to decide and invoke the tool correctly.

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?

The schema fully describes the only parameter (queue_id as a UUID with a description), so schema coverage is 100%. The tool description does not add any additional meaning about the parameter, and per the guidelines, the baseline for high schema coverage is 3.

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 clearly states the action ('Delete a queue') with a specific verb and resource, and distinguishes it from other delete tools by explicitly mentioning the queue and its associated runs. It also provides additional context about side effects and returns, making the purpose unmistakable.

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?

The description implies the primary use case (deleting a queue) and highlights an important side effect (interrupting active runs) that would inform a user's decision. However, it does not explicitly compare to alternative tools or state when not to use this operation, leaving some implicit context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteQueueAggregationDelete Queue AggregationA
DestructiveIdempotent
Inspect

Soft-delete an aggregation definition.

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier
definition_idYesThe aggregation definition's identifier

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the tool to be destructive, not read-only, and idempotent. The description adds meaningful context beyond the annotations by specifying that the deletion is 'soft,' implying recoverability or non-permanent removal. This complements the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, short sentence with zero wasted words. It front-loads the action ('soft-delete') and the target object ('aggregation definition') immediately, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter tool with rich annotations and a fully documented schema, the description covers the core operation sufficiently. The only minor gap is that it does not explain the post-deletion state or whether soft-deleted definitions can be restored, but the term 'soft-delete' implies recovery and the annotations already cover destructiveness and idempotency.

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%, with both queue_id and definition_id documented in the schema. The description itself adds no additional parameter meaning, but the schema fully identifies each parameter's purpose, matching the baseline for high schema coverage.

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 clearly states the action ('Soft-delete') and the resource ('an aggregation definition'), which is specific and distinguishes it from other delete tools like deleteQueue, deleteQueueLabel, or deleteQueueJsonSchema. Even without comparing schemas, an agent can tell exactly what this tool operates on.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no explicit guidance about when to use this tool versus alternatives such as createQueueAggregation, listQueueAggregations, refreshQueueAggregation, or a hypothetical hard delete. It relies entirely on the tool name and the word 'delete' to imply usage, with no prerequisites or contextual conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteQueueLabelDelete Queue LabelA
DestructiveIdempotent
Inspect

Delete a label from a queue. Cascade-deletes all assignments of this label on existing cases.

NameRequiredDescriptionDefault
label_idYesThe label's unique identifier
queue_idYesThe queue's unique identifier

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds the crucial behavioral detail of cascade-deleting all assignments on existing cases, which goes beyond the annotation's destructiveHint. It transparently communicates this side effect, though it doesn't mention idempotency or irreversibility explicitly (though annotations cover these).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that front-loads the action and includes the essential cascade detail. It is efficient and well-structured.

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 destructive delete operation, the description provides sufficient context: what is deleted and the cascade effect. No output schema is needed, and the description covers the relevant aspects without superfluous information.

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?

The input schema already provides descriptions for both parameters ('The label's unique identifier' and 'The queue's unique identifier') with 100% coverage. The description adds no further semantic information about the parameters, so it meets the baseline for high coverage.

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 clearly states the action ('Delete a label from a queue') and specifies the cascade-delete effect on assignments. It effectively distinguishes this tool from siblings like deleteQueue, deleteQueueAggregation, and updateQueueLabel.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage (when you need to delete a label and its assignments) but does not explicitly contrast it with alternatives like updateQueueLabel or deleteQueue. It lacks direct guidance on when to prefer this tool over similar ones.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteReadNotificationsDelete Read NotificationsA
DestructiveIdempotent
Inspect

Soft-delete all read notifications for the authenticated user's current team. Returns the count of notifications that were deleted. Destructive — only call on explicit user request. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations by disclosing that the operation is a soft-delete, that it returns the count of deleted notifications, and that it returns 404 when the Notification Center feature is disabled. It reinforces the destructiveHint with an explicit 'only call on explicit user request' warning. No contradiction with annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences carry all essential information: what the tool does, what it returns, destructive warning, and feature prerequisite. There is no filler, and the most important behavioral facts are front-loaded.

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 single-parameter destructive mutation with no output schema, the description is complete: it specifies the action, scope, return value, destructive nature, and an important error condition. The schema covers team_id semantics, and annotations cover the destructive and idempotent hints.

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?

The input schema already has 100% coverage for team_id, including detailed explanation of API key versus OAuth behavior. The description adds no new parameter-specific guidance beyond referring to the 'current team', which the schema already covers. Baseline 3 is appropriate.

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 states a specific verb and resource: 'Soft-delete all read notifications for the authenticated user's current team.' It clearly distinguishes this from sibling tools like deleteAllNotifications by specifying 'read' notifications, and it also clarifies the team scope.

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?

The description gives clear context: it deletes read notifications for the current team, is destructive, and should only be called on explicit user request. It also notes the Notification Center feature prerequisite and 404 behavior. It does not explicitly name alternatives like deleteAllNotifications, but the scope is clear enough for an agent to infer when this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteScheduleDelete ScheduleA
DestructiveIdempotent
Inspect

Delete a schedule. Owners may delete their own schedules; team superadmins may delete any schedule on agents in the current team. Deleting a schedule that belongs to an automation with revisions stops it for its owner at once; the automation's revisions keep the schedule for anyone else subscribed to it.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier
schedule_idYesThe schedule's unique identifier

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description goes well beyond them by disclosing the precise blast radius: deleting an automation-owned schedule stops it for the owner immediately, while other subscribers retain it via the automation's revisions. That is exactly the consequence context an agent needs before a destructive call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each carrying distinct information: the action, the authorization rule, and the side effect. The core action is front-loaded, and nothing is repeated from the schema or annotations.

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 two-parameter destructive mutation with no output schema, the description covers purpose, permissions, and downstream effects on both the owner and other subscribers. Nothing an agent needs in order to decide whether to call it is missing.

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% and both required UUID parameters (agent_id, schedule_id) are documented in the schema itself. The description adds no format or validation detail beyond what is already structured, so the baseline of 3 applies.

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?

States a specific verb and resource ("Delete a schedule") and immediately scopes it by ownership. It is clearly distinguishable from sibling tools like updateSchedule, createSchedule, and listAgentSchedules without opening a schema.

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?

The description gives explicit authorization preconditions: owners may delete their own schedules, team superadmins may delete any schedule on agents in the current team. It doesn't name an alternative action (e.g., updateSchedule to pause or modify instead), so the routing guidance is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteSecretDelete SecretB
DestructiveIdempotent
Inspect

Soft-delete an env-var secret. Deleting a team-shared secret requires lead builder role.

NameRequiredDescriptionDefault
idYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description reveals a role requirement (lead builder) and clarifies that the operation is a soft-delete, which adds behavioral context beyond the annotations. However, it does not mention reversibility, side effects, or what happens to related data, leaving some behavior implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise, containing only the essential action and a role requirement. It avoids any redundant or irrelevant information, making it easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple nature of the tool (single parameter, no output schema), the description provides sufficient context to understand the primary purpose and a key constraint. It lacks alternative usage guidance but is otherwise complete for basic decision-making.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter 'id' has no description in the schema or in the tool description. The schema provides type and format, but the description does not clarify what the id refers to (e.g., secret id, team id, etc.), adding minimal value beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly specifies the action ('soft-delete') and the resource ('env-var secret'), and adds a role requirement. It is unambiguous about the operation's nature, though it doesn't elaborate on what 'soft-delete' entails.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines1/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given on when to use this tool versus alternatives like deleteCredential or deleteConnection. There is no mention of preferred scenarios or conditions that would select this over other delete operations.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteSkillDelete SkillA
DestructiveIdempotent
Inspect

Delete a skill for the current team.

NameRequiredDescriptionDefault
skill_idYesSkill ID.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is covered. The description adds only the current-team scope; it does not disclose whether deletion is permanent, whether revisions are also removed, or what happens to dependent references.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, direct sentence with no filler or redundant wording. Every word contributes to defining the action, resource, and scope, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter delete operation, the combination of description, annotations, and schema is mostly sufficient. The description adds the current-team scope, which is useful. Minor gaps include not mentioning whether the deletion cascades to skill revisions or whether system skills are protected, but these are not essential for basic invocation.

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?

The schema has 100% description coverage for the single skill_id parameter, so the description does not need to repeat parameter details. The description adds no additional meaning beyond the schema, keeping this at the baseline score.

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 uses a specific verb ('Delete') and a clear resource ('skill'), and scopes the operation to the current team. This cleanly distinguishes it from sibling tools like deleteSkillRevision and deleteSkill-related file operations. The action is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: call this when you need to delete a skill belonging to the current team. However, it does not explicitly state when to use this tool versus alternatives, such as deleteSkillRevision, nor does it mention any conditions, prerequisites, or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteSkillRevisionDelete Skill RevisionA
DestructiveIdempotent
Inspect

Delete a draft or historic skill revision and its files. The active revision can't be deleted — activate another revision first.

NameRequiredDescriptionDefault
skill_revision_idYesSkill revision ID.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry destructiveHint=true and readOnlyHint=false; the description adds that the operation also removes the revision's files and that active revisions are protected. This is useful behavioral context beyond the structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences pack the action, scope, side effect, and a limitation with no filler. The key constraints are front-loaded before the prerequisite guidance.

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 one-parameter destructive operation with no output schema, the description is sufficient: it states what is deleted, what files are affected, and the one condition under which deletion fails. No critical operational detail is missing.

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 coverage is 100% and the schema already defines skill_revision_id with uuid format and description. The description's draft/historic framing hints at valid IDs, but it does not add substantially new parameter-level meaning.

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?

States a specific action (delete), resource (skill revision), scope (draft or historic), and explicitly excludes active revisions. This distinguishes it from deleteSkill and updateSkillRevision/promoteSkillRevision without needing to inspect schemas.

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?

Clearly indicates when it can be used (draft/historic revisions) and when it cannot (active revision), with a prerequisite instruction to activate another revision first. It does not name the exact sibling tool for promotion, so it stops short of full explicit routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteSkillRevisionFileDelete Skill Revision FileA
DestructiveIdempotent
Inspect

Delete a file from a skill revision. Deleting from a draft leaves the active revision untouched until the draft is promoted; deleting from the active revision changes what the skill runs immediately. SKILL.md can't be deleted. Historic revisions are read-only: create a draft from one to edit it.

NameRequiredDescriptionDefault
pathYesRelative path to the file inside the revision, e.g. scripts/helper.py.
skill_revision_idYesSkill revision ID.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructive=true and idempotent=true, and the description adds what those annotations cannot: the delayed-vs-immediate effect depending on revision state, the SKILL.md deletion prohibition, and the read-only nature of historic revisions. This is real behavioral context beyond the structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, front-loaded with the action, followed by the state-dependent effects and constraints. No filler and nothing repeated from the schema.

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 destructive two-param tool with no output schema, the description covers effect timing, protected files, and immutable-revision handling. An agent has everything needed to decide and call correctly.

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% for both required params (path with example, skill_revision_id with format), so the schema carries the load. The description adds no syntax or format detail for either parameter, making 3 the correct baseline.

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?

States a precise verb+resource ('Delete a file from a skill revision'), which cleanly separates it from deleteSkillRevision, deleteSkill, and deleteFile. The draft-vs-active distinction further pins down exactly what object is being mutated.

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?

Explains the consequences that determine when this is the right call: deleting from a draft is deferred until promotion, deleting from active takes effect immediately. It also states the read-only constraint on historic revisions and the workaround (create a draft). No alternative tool is named explicitly, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteSlackTriggerDelete Slack Channel TriggerA
DestructiveIdempotent
Inspect

Permanently delete a Slack channel trigger you own. The agent stops starting Runs for that channel. To keep the trigger but stop it firing, update it with enabled: false instead.

NameRequiredDescriptionDefault
trigger_idYesThe Slack channel trigger's unique identifier

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark destructiveHint=true and readOnlyHint=false, but the description adds important behavioral context: the deletion is permanent, the trigger will no longer start Runs for the channel, and ownership is required. This goes beyond the structured annotations and clearly discloses the real-world effect of the action.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences deliver the core action, the consequence, and the alternative to deletion. Every clause earns its place, and the most important information is front-loaded.

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 single-parameter deletion tool with rich annotations, the description is fully complete: it names the resource, the permanent nature, the post-deletion effect, and the ownership constraint. No critical decision-making information is missing.

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?

The schema covers 100% of the parameter descriptions, including the trigger_id format and its meaning as the Slack channel trigger's unique identifier. The description does not add additional parameter-level detail, so the baseline score of 3 is appropriate.

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 states a specific action—'Permanently delete a Slack channel trigger you own'—with a clear resource and scope. It also distinguishes itself from the related updateSlackTrigger tool by contrasting deletion with disabling via `enabled: false`.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when not to use this tool: 'To keep the trigger but stop it firing, update it with `enabled: false` instead.' It also notes the ownership prerequisite with 'you own,' so an agent can route correctly between deletion and update.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

deleteTeamInviteDelete Team InviteA
DestructiveIdempotent
Inspect

Revoke a pending invitation so its link and email can no longer be used. Accepts either a team invitation (requires Superadmin or above on the invitation's team) or a Clarity process invitation (requires the process creator or a team admin). Revoking one side also revokes its linked counterpart when a process invitation created both. An invitation already accepted or declined is refused with 409, including one accepted a moment before, and process access the invitee already holds through an earlier acceptance is kept, so revoking never undoes an acceptance.

NameRequiredDescriptionDefault
idYesID of the invitation to revoke. Accepts either a team invitation or a Clarity process invitation.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses key behaviors beyond annotations: that accepted/declined invites are refused, that revoking one side of a linked pair also revokes the other, and that previously-accepted access is retained. Annotations already show destructiveHint=true and idempotentHint=true, but the description adds crucial nuance about side effects and edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each dense with critical information. No fluff. The most important behavioral notes (what happens when accepted/declined) are front-loaded. Each sentence earns its place.

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?

Comprehensive for a two-parameter tool with no output schema. Covers acceptance states, cross-revocation, access retention, and permission requirements. No missing pieces an agent would need to decide correctness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already describes both parameters (id and team_id) with high coverage (100%). The description confirms the id accepts either type and adds context on team_id's fallback behavior (already in schema). It adds marginal value by reinforcing the dual-type acceptance.

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?

States a specific verb ('revoke') and resource ('pending invitation'), and clearly specifies the two types it accepts (team invitation or Clarity process invitation). The distinction from siblings like deleteClarityProcessInviteLink and deleteTeamInviteLink is implicit but clear due to the 'pending invitation' framing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use: for revoking pending invitations, and distinguishes behavior for accepted/declined invitations (refused with 409). It implies the alternative is createTeamInvite or bulkCreateTeamInvites, and notes the dual-sided revocation. No exclusions needed because it is a targeted delete operation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detachPulseDashboardConnectionDetach Pulse Dashboard ConnectionA
DestructiveIdempotent
Inspect

Detach a connection (data source) from a Duvo Pulse dashboard (requires edit access).

NameRequiredDescriptionDefault
artifactIdYes
connectionIdYes

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the operation destructive and idempotent, lowering the disclosure burden. The description adds the edit-access requirement and clarifies that 'connection' means 'data source', which is useful context beyond the annotations. It does not state whether the underlying connection is also deleted or remains available to other dashboards, but the annotations cover the core destructive profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the action and target, then adds the permission caveat. There is no redundant wording or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter destructive operation, the description plus annotations provide a reasonable baseline: action, target, permission, destructiveness, and idempotency. It is incomplete only in not explicitly linking parameters to their roles and not clarifying the fate of the connection after detach, which matters for a destructive tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description needs to compensate, but it does not explicitly map artifactId to the dashboard or connectionId to the connection. The domain terms 'dashboard' and 'connection' hint at the roles, but the mapping is left to inference, which is risky for a two-UUID parameter API.

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 uses a specific verb ('Detach') with a specific resource ('a connection (data source)') and target ('Duvo Pulse dashboard'), clearly distinguishing it from related operations like attachPulseDashboardConnection and deleteConnection. Including the edit-access requirement adds further precision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The semantics of 'detach a connection from a dashboard' imply this is the tool for removing a dashboard's link to a data source rather than deleting the connection entirely. However, it does not explicitly state when to prefer this over sibling tools such as deleteConnection or attachPulseDashboardConnection, nor does it provide when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detachRevisionLoginDetach Revision LoginB
DestructiveIdempotent
Inspect

Detach a login from a revision. Personal logins can only be detached by their owner; team-shared logins require builder permissions.

NameRequiredDescriptionDefault
agentIdYes
buildIdYes
exposedCredentialIdYes

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as destructive and idempotent. The description adds meaningful behavioral context beyond the annotations by detailing the permission requirements (owner vs. builder). This is useful for predicting whether the call will succeed and for setting expectations about access control.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and front-loaded: the first sentence states the core operation, and the second adds a valuable permission nuance. There is no redundant or filler content; every sentence contributes useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With three required parameters, zero schema descriptions, and no output schema, the description should do more to make the tool safely invocable. It omits how the parameters map to the operation, whether detaching affects the underlying credential, and any further behavioral details. The permission note is helpful but not sufficient for a complete picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, yet the description provides no explanation for agentId, buildId, or exposedCredentialId. While the parameter names are somewhat self-descriptive, the description does not connect 'login' to exposedCredentialId or clarify that buildId refers to the revision. The description fails to compensate for the lack of schema-level parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action and resource: 'Detach a login from a revision.' It is more specific than the name alone, and the additional detail about personal vs. team-shared logins adds scope. It does not explicitly distinguish itself from sibling tools like detachRevisionSecret, but the resource difference is largely self-evident.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides an authorization context: personal logins require owner permissions, team-shared require builder permissions. This helps an agent gauge whether the operation is permitted. However, it does not mention when to prefer this tool over related tools like attachRevisionLogin or detachRevisionSecret, so guidance is only partial.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detachRevisionSecretDetach Revision SecretA
DestructiveIdempotent
Inspect

Detach an env-var secret from a revision. Personal secrets can only be detached by their owner; team-shared secrets require builder permissions.

NameRequiredDescriptionDefault
agentIdYes
buildIdYes
credentialIdYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds value by explaining ownership-based permission differences (owner vs builder), which is not present in annotations and helps the agent predict authorization failures.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler. The core action is front-loaded, and the permission caveat is the only additional sentence, making the description easy to scan and process.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, mutating tool with three opaque UUID parameters and no output schema, the description is thinner than ideal. It covers the main action and permission model, but parameter semantics and what happens on failure or success are undocumented. Annotations cover destructive/idempotent behavior, so this is adequate but not complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description names none of the three required parameters. It only loosely implies that credentialId refers to an env-var secret, but agentId, buildId, and credentialId are left entirely to inference from their names and UUID formats.

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?

States a specific verb ('Detach'), a specific resource ('env-var secret'), and a target ('from a revision'). This clearly distinguishes the tool from the sibling attachRevisionSecret and from detachRevisionLogin, which targets a different resource type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives relevant permission context (personal vs team-shared secrets) but never explicitly says when to prefer this tool over alternatives or when not to use it. The intended use is implied by 'Detach an env-var secret from a revision,' but no alternative routing or exclusion guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dismissClarityTeamAssignmentSuggestionDismiss Clarity Team Assignment SuggestionA
Destructive
Inspect

Dismiss a pending Process Landscape team-assignment suggestion without changing the node's owner (manager+).

NameRequiredDescriptionDefault
nodeIdYes
suggestionIdYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the mutation profile is covered. The description adds genuinely useful context the annotations lack: the write is scoped to the suggestion and explicitly leaves the node's owner unchanged, and it discloses the manager+ authorization requirement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence, front-loaded with the action and resource, then the crucial scoping and permission qualifiers. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, permission level, and the scope of the destructive write, which is enough for an agent to act safely. However, for a two-parameter required-arg tool with zero schema documentation, the absence of any explanation of nodeId vs suggestionId leaves a real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% with no property descriptions; nodeId and suggestionId are UUIDs with no textual explanation. The description does not mention either parameter or their roles (which node, which suggestion), so it fails to compensate for the coverage gap.

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?

Specific verb (dismiss) + resource (a pending Process Landscape team-assignment suggestion), with the exact non-effect stated ('without changing the node's owner'). This cleanly separates it from the sibling acceptClarityTeamAssignmentSuggestion without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'pending' and the '(manager+)' permission hint give implied usage context, but the description never names the alternative (acceptClarityTeamAssignmentSuggestion) or states when not to use it. An agent must infer the routing from the verb alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

dismissNotificationDismiss NotificationA
DestructiveIdempotent
Inspect

Dismiss an important notification for the authenticated user. A row pinned to their Important section is unpinned and the card stays, because the connection is still broken; a row that is not pinned for them — one they cannot reconnect themselves — is removed from their feed instead, matching what the card's Dismiss button does. Only important notifications (currently: connection_broken) can be dismissed. Idempotent. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
idYesThe notification's unique identifier

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by spelling out exactly what is destroyed versus preserved: a pinned row is unpinned and the card remains, while a non-pinned row is removed from the feed. It also discloses idempotency and the feature-gating failure mode (404 when Notification Center is not enabled for the team).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Information-dense and front-loaded, with the core action stated first and behavioral edge cases following. The pinned/non-pinned clause is long and em-dash heavy, making it slightly harder to parse than necessary, but every sentence carries substantive meaning.

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?

No output schema exists, so the description compensates by covering the meaningful return behaviors (idempotent success, 404 when the feature is disabled) and the full destructive semantics. For a single-parameter mutation with partial annotation coverage, nothing an agent needs to call it correctly is missing.

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% for the single 'id' parameter, so the schema already carries the parameter documentation. The description adds no syntax or format detail about the identifier, which is the correct baseline when structured data does the heavy lifting.

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?

States a specific verb and resource ('Dismiss an important notification for the authenticated user') and immediately scopes it to important notifications only, which distinguishes it from siblings like markNotificationRead, deleteReadNotifications, and deleteAllNotifications. An agent can identify this tool's distinct role without opening the schema.

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 an explicit eligibility constraint ('Only important notifications (currently: connection_broken) can be dismissed') and anchors the expected outcome to the product's Dismiss button, which clarifies intent. It never names the sibling alternatives (markNotificationRead, deleteReadNotifications) for non-important notifications, so the when-not-to-use-this routing is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

downloadSkillDownload SkillA
Read-onlyIdempotent
Inspect

Download a custom skill as a ZIP archive. Only custom (team-owned) skills can be downloaded.

NameRequiredDescriptionDefault
skill_idYesSkill ID.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnly, idempotent, and non-destructive behavior. The description adds the output format (ZIP archive), which is useful context. It does not contradict the annotations and covers the primary behavioral detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no fluff. It states the purpose and the key constraint (custom-only) efficiently, making it easy to parse.

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 simple download operation with a single parameter, the description is complete. It specifies the output format and the condition (custom-only), which is sufficient for an agent to decide and invoke correctly without further details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides format and pattern for skill_id. The description's mention of 'custom skill' clarifies that skill_id should reference a custom (team-owned) skill, adding meaning beyond the bare 'Skill ID.' schema description.

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 clearly states the action (download), the resource (custom skill), and the output format (ZIP archive). It also distinguishes from listSkills and getSkillFileContent by specifying the ZIP archive format and the custom-skill restriction.

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?

The description explicitly states a when-not condition: only custom (team-owned) skills can be downloaded. It implies when to use this tool (when a ZIP archive of a custom skill is needed) but does not explicitly mention alternative tools like getSkillFileContent for system skills, hence a slight deduction.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

duplicateAgentDuplicate AgentAInspect

Duplicate an existing agent into a new agent named "Copy of ", carrying over its configuration. Use the include_* flags in the (optional) body to control what is copied; all default on except memory. Requires the Lead Builder team role or above.

NameRequiredDescriptionDefault
agent_idYesThe ID of the agent to duplicate
include_aopNoCopy the agent's operating procedure (AOP) and its handover targets. Defaults to true.
include_queueNoCopy the assigned Queue. Defaults to true.
include_memoryNoCopy what the agent has learned so far (its Memory). Defaults to false. Memory can only be copied from the Duvo app — requesting it here returns an error.
include_pluginsNoCopy installed plugins. Defaults to true.
include_connectionsNoCopy connected accounts (Connections) and their selected tools. Defaults to true.
include_skills_filesNoCopy attached Skills and Files. Defaults to true.
include_logins_secretsNoCopy saved Logins and Secrets. Defaults to true.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only provide generic hints (readOnlyHint false, destructiveHint false), so the description adds meaningful behavioral context: the new agent's naming convention, that configuration is carried over, that all include flags default on except memory, and the required role of Lead Builder or above. This goes beyond the structured annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each with a distinct purpose: state the operation and naming, explain the include_* flags and defaults, and state the permission requirement. There is no filler or repetition of schema fields; the most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter tool with no output schema, the description covers the core semantics, default behavior, and access control. It does not explicitly describe the return value or potential error cases, but the clear naming and include-flag guidance make it adequate for correct invocation in most scenarios.

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 input schema already fully documents every parameter, including defaults for all include_* flags. The description's mention of include_* flags and 'all default on except memory' adds no semantic detail beyond the schema, so the baseline 3 applies.

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 states a specific action ('Duplicate'), the resource ('an existing agent'), and the exact outcome (a new agent named 'Copy of <name>'). This clearly distinguishes it from sibling tools like createAgent, updateAgent, and moveAgent without needing to inspect their schemas.

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?

The description makes the intended use obvious: copy an existing agent with its configuration and control which parts are copied via the include_* flags. It does not explicitly name alternatives or state when not to use it, but the duplication semantics are clear enough to guide selection against createAgent or updateAgent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

duplicateAutomationDuplicate AutomationAInspect

Duplicate an automation into a new one named "Copy of ", copying what it runs today: its live agents and builds, its queues (empty), the routing and handovers between them, and each agent's Memory when the team holds Memory and the agent has it on. The caller's own triggers and schedules are copied switched off, so the copy starts no run until they turn them on; other members' triggers and schedules are not copied. An automation built by hand also gets its Policy: sections, questions, answers, and which agents read them. Cases and run history are not copied. A Module demo, and a Module automation with Policy questions, can't be duplicated.

NameRequiredDescriptionDefault
automation_idYesThe automation to duplicate

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes far beyond the thin annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=false). It discloses the naming convention ("Copy of <name>"), exactly what is copied (live agents/builds, empty queues, routing, handovers, Memory under conditions), that triggers/schedules are copied switched off, that other members' triggers are excluded, and that cases/run history are not copied. That is unusually rich mutation disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and long, but essentially every clause (naming, copied artifacts, trigger state, exclusions, restrictions) carries decision-relevant information, and the primary action is front-loaded. Slightly run-on as a single block, but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-output-schema, single-parameter mutation tool the behavioral picture is close to complete. The one omission is what the call returns (e.g. the new automation's id), which would help an agent chain follow-up calls, but the copy semantics themselves are fully covered.

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?

Only one parameter (automation_id), and schema description coverage is 100%, so the schema already documents it fully. The description adds nothing about the identifier itself; per the high-coverage baseline this is a 3.

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?

States a specific verb (duplicate) and resource (automation) and then enumerates precisely what the copy does and does not contain. An agent can distinguish it from siblings like duplicateAgent or duplicateClarityProcess purely from the text.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description supplies strong exclusion rules (Module demos and Module automations with Policy questions can't be duplicated), which is real usage guidance. However, it never names an alternative tool or states positive when-to-use conditions relative to createAutomation or the other duplicate* siblings, so routing is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

duplicateClarityProcessDuplicate Clarity ProcessAInspect

Duplicate a Clarity process with its analysis, captures, message history, and, for v2 processes, its live current map and automation proposal. Requires a team manager role.

NameRequiredDescriptionDefault
idYesSource Clarity process id

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a mutating operation (readOnlyHint=false, destructiveHint=false), and the description adds meaningful behavioral context: what data is included in the duplicate, a version-specific behavior for v2 processes, and the required team manager role. It does not state the outcome format or whether a new process ID is returned, but the role and content details go beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single well-structured sentence that front-loads the core action and resource, immediately follows with the key included contents, and adds the role requirement at the end. Every phrase provides useful information, with no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simple single-parameter schema and absence of an output schema, the description gives enough operational context: what is copied, the version-specific scope, and the permission requirement. It could be slightly more complete by noting what is returned or where the duplicate is created, but these are minor gaps for a straightforward duplication operation.

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?

The schema covers the single parameter id with a description ('Source Clarity process id'), so the description does not need to add much. The description confirms the parameter refers to the process being duplicated, but it does not add additional semantic detail beyond what the schema already provides. This aligns with the baseline for full schema coverage.

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 uses the specific verb 'Duplicate' with the clear resource 'Clarity process' and enumerates exactly what gets copied: analysis, captures, message history, and for v2 processes, live current map and automation proposal. This distinguishes it from sibling tools like createClarityProcess, deleteClarityProcess, and duplicateAgent without needing to open their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies its use case clearly: when you need to duplicate an existing Clarity process and preserve its associated data. It also adds the role prerequisite 'Requires a team manager role.' However, it does not explicitly state when to use this tool over createClarityProcess or how it differs from other duplication tools such as duplicateAgent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

duplicatePulseDashboardDuplicate Pulse DashboardAInspect

Duplicate a Duvo Pulse dashboard, producing an idle clone of the current rendered dashboard. The conversation history, shares, and connections are not copied.

NameRequiredDescriptionDefault
artifactIdYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations only indicate that this is not read-only and not destructive. The description adds concrete side-effect detail by stating that conversation history, shares, and connections are not copied and that the clone is 'idle.' This goes beyond what the annotations already communicate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with the action and scope front-loaded. The second sentence adds meaningful exclusions without unnecessary detail. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter mutation with no output schema, the description adequately covers what the tool produces and what is not carried over. It does not explain return values or how the clone is named, but those are not essential for invoking the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description never mentions 'artifactId' or explicitly states that it identifies the source dashboard to duplicate. The single-parameter shape makes the role somewhat inferable, but the description does not compensate for the missing schema documentation.

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 clearly states the action ('Duplicate'), the resource ('Duvo Pulse dashboard'), and the expected result ('idle clone of the current rendered dashboard'). It also distinguishes this tool from other duplication siblings by specifying the dashboard resource and the non-copied elements.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool should be used when an existing Pulse dashboard needs to be cloned, but it does not explicitly say when not to use it or contrast it with related tools like createPulseDashboard or restorePulseDashboardVersion. No alternatives or exclusions are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

evaluateQueueAggregationEvaluate Queue AggregationAInspect

Evaluate an aggregation definition against the current data without persisting it.

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier
definitionYes

TDQS

A3.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The only disclosed behavior is non-persistence of the definition; the tool does not say whether it modifies other state, whether the queue must exist, or whether evaluation has costs/limits. Annotations give readOnlyHint=false, so the description should take on more burden to clarify side effects, but it does not.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence front-loads the action and immediately states the key non-persistence property. No filler or redundant restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a complex tool with a nested definition schema and no output schema, but the description does not mention what the evaluation returns, how errors are surfaced, or any prerequisite such as queue existence. The non-persistence note is useful, but a significant amount of operational context is missing.

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?

The schema documents queue_id and the definition object's structure well, and the description clarifies that 'definition' is an aggregation definition. However, the description adds no meaning for queue_id or the semantics of measures/filters/dimensions beyond their names and enums.

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 names a specific verb ('Evaluate'), a resource ('an aggregation definition'), and a distinguishing scope ('against the current data without persisting it'). This clearly separates it from createQueueAggregation, getQueueAggregationResult, and refreshQueueAggregation.

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 a clear context: use it for a dry-run evaluation of a definition before persistence. It does not explicitly name alternatives or exclusion cases, but the non-persistence wording makes the intended scenario obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exportCasesExport CasesAInspect

Export a queue's cases, respecting the same status, severity, failure source, approval, priority, label, date-range, json_data field, and free-text filters as the list view. Set awaiting_my_approval to export only the cases holding an unanswered approval row assigned to you; like the list view it resolves to the authenticated caller, so a credential with no user behind it is rejected rather than exporting an empty file. format: "json" (default) returns a re-importable JSON payload; format: "csv" returns a text/csv file with the columns id, title, status, priority, labels, created_at, updated_at, completed_at, postponed_to, data.

NameRequiredDescriptionDefault
formatNojson
searchNo
filtersNo
sort_byNocreated_at
queue_idYesThe queue's unique identifier
sort_orderNoasc

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds real behavioral context beyond annotations: default vs csv format outputs, the exact csv column set, re-importability of the JSON payload, and the failure behavior for credential-less callers. Annotations are present but poorly suited to this operation (readOnlyHint=false and idempotentHint=false on an export), and the description does not address that mismatch, leaving a small gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core export semantics before the edge-case credential behavior and the format details. Dense but every clause carries information; the credential-rejection clause is niche but genuinely useful for avoiding a silent empty export.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description compensates by describing the JSON payload as re-importable and listing the csv columns. Given a nested filters object and 6 parameters, it covers most of what a caller needs, but omits sorting behavior and any size/async-export limits that a large export would hit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 17% schema description coverage, the description must carry the parameter burden, and it largely does: it enumerates the filter families (status, severity, failure source, approval, priority, label, date-range, json_data, free-text), pins down awaiting_my_approval, and explains both format values. It says nothing about sort_by/sort_order or the date-range syntax, so the compensation is not complete.

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?

States a specific verb and resource — 'Export a queue's cases' — with the scope (single queue) and the two output shapes spelled out. This clearly differentiates it from listCases/searchCases (viewing) and from unrelated export siblings like exportPulseDashboardHtml. An agent can identify the tool's function without opening the schema.

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 anchors usage by stating the filters mirror 'the list view' and describes the one non-obvious selector, awaiting_my_approval, including the credential prerequisite (a caller with no user is rejected rather than producing an empty file). However it never explicitly says when to choose export over listCases or searchCases, so the routing is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

exportPulseDashboardHtmlExport Pulse Dashboard HtmlB
Read-onlyIdempotent
Inspect

Render a Duvo Pulse dashboard to a self-contained static HTML snapshot (text/html, data baked in). 404 until the first generation turn has produced HTML; 409 for an openui dashboard, whose substrate this exporter cannot render.

NameRequiredDescriptionDefault
themeNolight
artifactIdYes

TDQS

B3.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds meaningful behavioral context by disclosing the 404 condition (no HTML produced yet) and the 409 condition (unrenderable openui dashboard), which go beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded with the primary action, followed by two important status-code caveats. It contains no filler, though the constraints could be slightly better organized for readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core behavior and important error conditions, but it leaves gaps: it does not explain what 'openui dashboard' means, does not clarify the relationship to getPulseDashboardHtml, and does not mention how theme affects the output. These gaps matter for an agent deciding whether and how to call this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description should compensate by explaining artifactId and theme meanings. It does not mention either parameter, leaving artifactId's role implicit and theme's effect on the rendered HTML undocumented. Parameter names help somewhat, but the description adds no real semantic value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool renders a Duvo Pulse dashboard into a self-contained static HTML snapshot with data baked in. It identifies the resource and the output format, though it does not explicitly differentiate itself from sibling tools like getPulseDashboardHtml or getPulseDashboardPdf.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no explicit guidance on when to use this tool versus alternatives such as getPulseDashboardHtml or getPulseDashboardVersionHtml. The 404 and 409 notes describe preconditions and failure cases, but they do not help an agent choose between sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

fileSuggestedClarityProcessesFile Suggested Clarity ProcessesAInspect

File every unfiled process the viewer can see into its suggested folder

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotation contradiction: the description says a mutating action while annotations set readOnlyHint=false. It adds useful scope (bulk, only visible, only unfiled, destination is suggested folder) beyond the annotations, but doesn't disclose possible partial failures, reversibility, or the effect on already-filed processes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that states the action, scope, and destination with no filler. Every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-optional-parameter tool with no output schema, the description gives enough to invoke correctly. It could add a note about mass execution or confirmation behavior, but nothing critical is missing for selection and invocation.

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?

The only parameter, team_id, is fully described in the schema including fallback and OAuth behavior. With 100% schema description coverage, the description doesn't need to add parameter details; baseline 3 is appropriate.

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 names a specific verb ('File'), a bounded resource ('every unfiled process the viewer can see'), and the destination ('its suggested folder'). This clearly distinguishes it from per-suggestion accept/dismiss tools and manual move operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'every unfiled process the viewer can see' gives an implicit trigger condition for using this bulk filing tool, but it does not explicitly contrast with alternatives like acceptClarityCaptureSuggestion, dismissClarityCaptureSuggestion, or moveClarityProcessesToFolder. An agent has to infer when to choose this over those siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

finalizeCaseAttachmentFinalize Case AttachmentAInspect

Confirm an uploaded case attachment against storage. Answers with the attachment in its settled state — ready when the bytes are present, failed (with a reason) when the upload never completed.

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier
queue_idYesThe queue's unique identifier
attachment_idYesThe attachment's unique identifier

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

It discloses the operation's outcome semantics—ready when bytes exist, failed with a reason when the upload never completed—beyond the raw annotation flags. It does not detail side effects or authorization requirements, but no contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences front-load the main action and then specify the outcome states. No filler or repetition of schema fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter tool with no output schema, the description adequately explains the return semantics and the purpose. It could add the ordering relative to createCaseAttachmentUploadUrl, but the core calling context is present.

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 three UUID parameters are already fully documented. The description adds no parameter-specific meaning, so it earns the baseline for high schema coverage.

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 names a specific action ('Confirm an uploaded case attachment against storage') and the concrete output states ('ready'/'failed'). This distinguishes it from sibling upload, download, and listing tools even without naming them.

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?

The context is clear: use it after an upload to verify that the bytes are present and settled, and interpret the ready/failed response. It does not explicitly name alternatives or state when not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

finalizeClarityOrganizationInterviewFinalize Clarity Organization InterviewAInspect

Manually mark an in-progress organization interview as complete without requiring final media uploads

NameRequiredDescriptionDefault
orgIdYes
interviewIdYesThe organization interview ID

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds useful behavioral context beyond the annotations by noting this is a manual override that does not require final media uploads. However, it does not disclose side effects, such as whether the interview becomes immutable, whether this action can be reversed, or what happens if the interview is already complete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. Every phrase—'manually', 'in-progress', 'as complete', 'without requiring final media uploads'—adds meaningful detail that helps an agent understand the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter state-transition tool with no output schema, the description captures the core action and the key condition. Yet it omits details an agent might need, such as the success/return behavior, whether finalizing is irreversible, and any validation constraints beyond the interview being in-progress.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema documents 'interviewId' but leaves 'orgId' completely undescribed, and the description does not compensate by explaining the role of either parameter. The phrase 'organization interview' hints at the resource type, but the description adds no meaning beyond the property names and the one existing schema description.

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 states a specific action ('mark as complete'), a specific resource ('organization interview'), and a distinctive condition ('without requiring final media uploads'). This clearly differentiates it from related tools like updateClarityOrganizationInterview or the upload-completion flow.

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?

The description gives clear context: this is for manually finalizing an in-progress interview, bypassing the usual media upload requirement. However, it does not explicitly state when not to use it or name alternatives, such as updateClarityOrganizationInterview for other edits or the normal upload-based completion path.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generateAutomationProcessMapGenerate Automation Process MapAInspect

Start the setup step Generate current process map for a Module automation being set up, the same as pressing it in the web app: Duvo writes the map of how the work runs today from the uploaded files, the interviews and the Policy. Returns 202 at once; the map takes a few minutes and appears on the setup's Current Process step (url). Over a map the team already has, it writes a new version. Refused with 409 while required Policy questions are open, a file or interview is still being transcribed, nothing usable is uploaded, or Duvo is already writing the map or the proposal, and with 403 unless the caller created the process or is a Lead Builder or above. Confirm with the user before calling: say it writes the map from what setup has collected. Next comes generateAutomationProposal.

NameRequiredDescriptionDefault
automation_idYesAutomation ID

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: 202 async acceptance, multi-minute duration, where the result lands (`url` on the Current Process step), versioning over an existing map, and the full set of 409/403 refusal causes including permission tiers (creator or Lead Builder+). Only gap is that it doesn't discuss whether an in-flight version can be cancelled or what the 202 payload contains, so not quite a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Content is front-loaded with the action, but the description is one dense run-on sentence packing refusals, permissions and sequencing into comma-chained clauses. Nothing is wasted, yet the 409/403 causes would be far easier to act on as a short list.

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 single-parameter async mutation with no output schema, it covers timing (202, minutes), result location (`url`), idempotency-adjacent behavior (writes a new version), failure modes and authorization. An agent has everything needed to call it correctly and set expectations.

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?

Only one parameter and schema coverage is 100%, so the schema fully documents `automation_id`. The description never mentions the parameter or its constraints (e.g. the UUID must belong to a setup the caller owns), so baseline 3 applies — schema carries the load.

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?

States a specific verb and resource ('Generate current process map for a Module automation being set up') and anchors it to the concrete UI action it mirrors ('the same as pressing it in the web app'). It also names the sibling that follows it (`generateAutomationProposal`), so an agent can place it in the workflow without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use (setup step for a Module automation), an explicit precondition ritual ('Confirm with the user before calling: say it writes the map from what setup has collected'), and the exact successor step. Also enumerates when-not-to-call via 409/403 conditions, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generateAutomationProposalGenerate Automation ProposalAInspect

Approve the current process map of a Module automation being set up and start writing the automation proposal from it, the same as the setup's Approve and continue in the web app. The proposal says what Duvo automates, what stays with the team and where work hands over. Returns 202 at once; the proposal takes a few minutes and appears on the setup's Automation Proposal step (url). Needs the team's own live current process map (call generateAutomationProcessMap first) and no proposal yet; current_process_snapshot_id, when given, must be that live map. Refused with 409 otherwise, or while required Policy questions are open or Duvo is already writing, and with 403 unless the caller created the process or is a Lead Builder or above. Confirm with the user before calling: say that approving the map writes the proposal from it. Next comes approveAutomationProposal.

NameRequiredDescriptionDefault
automation_idYesAutomation ID
current_process_snapshot_idNoThe current process map being approved. Must be the live map; leave out to approve whichever map is live.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Far exceeds the annotations: it discloses that the call is asynchronous (202 returned immediately, proposal takes minutes), where the result surfaces (`url` on the Automation Proposal step), permission requirements, refusal codes, and an explicit instruction to confirm with the user first because approving the map is what triggers the write. This is consistent with readOnlyHint=false and destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and the UI analogue, then prerequisites, errors, permissions, and next step in a logical order. It is dense and slightly run-on in places, but nearly every clause carries operational information.

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?

No output schema exists, and the description compensates fully by describing the return (202 immediately) and where the eventual result appears. With two parameters, async behavior, and a permission gate, nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real constraint semantics: the snapshot must be the team's live map, and omitting it approves whichever map is live. That is meaning beyond the schema's UUID pattern and 'leave out to approve whichever map is live' note.

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?

States a specific verb and resource (approve the current process map, start writing the automation proposal) and anchors it to a known UI action ("Approve and continue"). It also explains what the output artifact is (what Duvo automates, what stays with the team, where handover happens), so it is unmistakable against siblings like generateAutomationProcessMap and approveAutomationProposal.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit prerequisites (must call generateAutomationProcessMap first, must have no existing proposal), explicit exclusions and refusal conditions (409 if the map isn't live, a proposal exists, Policy questions are open, or Duvo is already writing; 403 unless creator or Lead Builder), and names the next step approveAutomationProposal.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generateClarityPortfolioIntelligenceGenerate Clarity Portfolio IntelligenceAInspect

Generate portfolio intelligence from all completed clarity processes. Returns 202 Accepted immediately and processes in background.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as non-read-only and non-idempotent; the description adds the valuable behavioral detail that it returns 202 Accepted immediately and does the work asynchronously. This tells the agent not to expect a synchronous payload. It doesn't contradict any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One tight sentence with the action front-loaded and the async behavior in a short second clause. No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an async one-parameter action with annotations and a fully documented schema, the description covers the key invocation behavior (accepted immediately, background processing). It could improve by pointing to getClarityPortfolioIntelligence for later retrieval, but the sibling name makes that inferable, so the gap is minor.

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?

The only parameter, team_id, has a full schema description covering UUID format, the API-key vs OAuth behavior, and fallback semantics. With 100% schema coverage, the description does not need to add parameter details, so the baseline 3 applies.

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 uses a specific verb ('Generate') with a distinct resource ('portfolio intelligence') and a clear source scope ('from all completed clarity processes'). This separates it from sibling retrieval tool getClarityPortfolioIntelligence and from generateClarityProcessLandscape/Snapshot.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description indicates when it is relevant (intelligence over completed clarity processes) and sets expectations for an async fire-and-forget call (202, background processing). However, it does not explicitly contrast with getClarityPortfolioIntelligence for retrieving results or state when not to call it, so the guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generateClarityProcessLandscapeGenerate Clarity Process LandscapeBInspect

Start a process-landscape generation run for the organization from its eligible Clarity captures (organization executives and owners)

NameRequiredDescriptionDefault
orgIdYes

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey that this is not read-only, not idempotent, and not destructive; the description adds that the run draws on eligible captures from organization executives/owners, which is useful scoping. It does not disclose side effects, return value, or async behavior, but the annotation set lowers the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the core action, and no filler. The parenthetical 'organization executives and owners' is compact but slightly ambiguous, so it is not a perfect 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description does not state what the tool returns, whether the generation run is asynchronous, how the agent can monitor or retrieve the result, or what prerequisites must be true before starting. For a low-complexity tool with no output schema, this leaves meaningful gaps.

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?

With a single parameter (orgId) and 0% schema description coverage, the description only indirectly maps to it by saying 'for the organization.' This gives the agent the basic semantic link but does not explicitly explain orgId format, source, or how it affects eligibility.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Start') and a specific resource ('process-landscape generation run'), and it adds an input source ('eligible Clarity captures'), so an agent can tell this is the initiating tool for landscape generation rather than, say, getClarityProcessLandscape. It does not explicitly name or differentiate against a sibling like generateClarityProcessSnapshot, which would push it to a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The context is clear: it is used to start a landscape-generation run for an organization based on eligible Clarity captures. However, it gives no explicit when-to-use vs alternatives, no preconditions beyond eligibility, and no mention of when a different generation or snapshot tool should be chosen.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generateClarityProcessSnapshotGenerate Clarity Process SnapshotAInspect

Trigger a snapshot generation pipeline for a v2 clarity process, selected by kind. current_process runs the generateCurrentProcess pipeline (body fields are proposal-only and rejected); transformation_proposal runs the generate or regenerate proposal pipeline. Returns 202 immediately and finalises asynchronously via the cc-server webhook stream.

NameRequiredDescriptionDefault
kindYesSnapshot kind to list
process_idYesThe clarity process id
custom_guidanceNoAutomation proposals only: optional freeform guidance for this generation. Used as high-priority design guidance, not source-of-truth evidence.
regenerate_fromNoAutomation proposals only: id of a prior proposal snapshot to refine. When supplied, runs the regenerate pipeline using that proposal's current-process snapshot as the anchor and the extra captures collected since.
source_snapshot_idNoAutomation proposals only: id of the current-process snapshot to anchor the new proposal to. Defaults to the latest snapshot for the process.
transformation_aggressivenessNoTransformation proposals only: the transformation appetite. `aggressive`, `conservative`, and `none` redesign around Duvo automation with decreasing freedom to change the process; `optimize` standardizes and streamlines the process while every step stays performed by people.aggressive

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses critical runtime behavior beyond annotations: 'Returns 202 immediately and finalises asynchronously via the cc-server webhook stream' and notes that body fields are proposal-only and rejected for `current_process`. Annotations (readOnlyHint=false, idempotentHint=false) give little context, so this description carries the transparency burden and largely fulfills it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences with the core action front-loaded in the first sentence and async behavior in the second. No filler; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a trigger tool with no output schema, it covers pipeline selection, async handoff, and field restrictions, which is sufficient. Minor omission: no mention of how to correlate the eventual webhook event back to this invocation, but that is not required to call the tool correctly.

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 schema already documents each parameter. The description adds a useful note about proposal-only fields being rejected, but does not restate syntax, enums, or constraints. Thus it only marginally supplements what the schema already provides.

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?

States a specific verb ('Trigger'), resource ('snapshot generation pipeline for a v2 clarity process'), and disambiguates two kinds with distinct pipelines (`current_process` vs `transformation_proposal`). Clearly distinguishes this generation action from sibling save/get/promote/revert snapshot tools.

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?

Clearly explains the two kind options and the triggers for each (generateCurrentProcess vs generate/regenerate proposal), including the fact that `current_process` rejects proposal-only fields. However, it does not explicitly contrast this tool with sibling tools like `getClarityProcessSnapshot` or `saveClarityProcessSnapshot`, so alternative selection is inferred rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generateRevisionGenerate RevisionAInspect

Generate agent instructions or code into a saved draft. Poll the returned builder run, answer questions if requested, then accept or decline the reviewed checkpoint. This never activates the revision.

NameRequiredDescriptionDefault
promptYesInstructions for generating or refining this agent or code step.
run_idNoOptional run ID for context
build_idYesSource revision to generate or refine.
process_idNoOptional process ID for context
conversationNoOptional voice conversation transcript
draft_file_idNoTemporary source file for this AOP draft. It is not kept on the Agent.
insight_indexNoOptional insight index for context
draft_file_idsNoTemporary source files for this AOP draft, in attachment order. They are not kept on the Agent.
previous_build_idNoPrevious build ID for sandbox reuse
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, destructiveHint=false, idempotentHint=false), the description adds real behavioral context: generation is asynchronous via a returned builder run, it involves a reviewed checkpoint, and it 'never activates the revision.' It doesn't cover auth or rate limits, but it meaningfully extends the structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: purpose, then workflow, then the key non-activation constraint, all front-loaded. Every sentence earns its place, though the phrase 'answer questions if requested' is slightly terse about who is asking.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter tool with no output schema, the description usefully explains the return behavior (poll the builder run, review checkpoint) and the non-activation guarantee. Remaining parameter depth is fully carried by the 100%-coverage schema, so it is largely complete.

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 schema already documents all 10 parameters in detail. The description adds no parameter-level meaning beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Generate agent instructions or code into a saved draft.' This clearly conveys what is produced. It doesn't explicitly contrast with close siblings like createRevision or acceptRevisionGeneration, so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It describes the post-call workflow (poll the builder run, answer questions, accept/decline the checkpoint), which implies usage. But it never states when to choose this over alternatives such as createRevision or updateRevision, leaving selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAgentGet AgentA
Read-onlyIdempotent
Inspect

Get an agent by ID. The response carries no revision config: use listAgentRevisions and getRevision for a revision, and getRevisionBody to read a large AOP in character ranges.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/closed-world, so the safety profile is covered. The description adds real behavioral value beyond that by disclosing a limitation of the payload itself — no revision config is returned — and where that data lives instead.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with zero filler; the purpose is front-loaded and the follow-up sentence carries only the routing information an agent would otherwise have to discover by trial and error.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read with no output schema, the description supplies the critical missing context about what the response omits and how to get it. Remaining gaps (e.g., not-found behavior, pagination-irrelevance) are minor for this operation.

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?

Only one parameter with 100% schema coverage; the description's 'by ID' merely restates the agent_id field already fully documented by the schema. Baseline 3 applies since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Get an agent by ID'), which is unambiguous against the large sibling list, and further clarifies that the returned object excludes revision config. It stops short of differentiating from near-neighbors like getAgentMemoryFile or getAgentSuggestion, but the core purpose is unmistakable.

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?

Gives explicit routing: when you need a revision, use listAgentRevisions/getRevision, and getRevisionBody for large AOPs read by character range. There is no stated when-not for this tool itself (e.g., versus listAgents), but the alternative-path guidance is concrete and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAgentCaseTriggerGet Agent Case TriggerA
Read-onlyIdempotent
Inspect

Retrieve a single case trigger by id.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier
trigger_idYesThe case trigger's unique identifier

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the description does not need to re-state safety. The description adds no extra behavioral context beyond 'retrieve a single... by id', such as whether a missing trigger yields a 404 or whether the agent_id is scoped to the caller's organization. With no contradiction and no additional disclosure burden, a 3 reflects that the description is adequate but adds minimal behavioral value over annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, short sentence that conveys the essential operation without any filler or redundant detail. It is appropriately front-loaded with the action verb, and every word earns its place. There is no reason to expand it further.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-by-id tool with two required UUID parameters, full schema coverage, and annotations covering idempotency and non-destructiveness, the description plus schema and annotations are nearly complete. The only minor gap is that the tool does not have an output schema, and the description does not state what the returned trigger object looks like or whether it includes nested fields, so an agent must infer the return shape.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: both agent_id and trigger_id have UUID format and pattern constraints plus descriptive text ('The agent's unique identifier', 'The case trigger's unique identifier'). The description itself references 'by id', which aligns with the trigger_id parameter. Since the schema fully documents both parameters, the description does not need to add more; the naming and formats make the semantics unambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Retrieve a single case trigger by id' clearly identifies the verb (retrieve), resource (case trigger), and lookup key (id). It stands apart from CRUD siblings like createAgentCaseTrigger, updateAgentCaseTrigger, and deleteAgentCaseTrigger, but does not explicitly distinguish itself from listAgentCaseTriggers or listAgentTriggers, so it loses a point for not naming those alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a read-only lookup use case, and annotations confirm it is idempotent and non-destructive. However, it provides no explicit guidance on when to choose this tool over listAgentCaseTriggers (e.g., when you need a single trigger rather than all triggers for an agent), nor does it mention that agent_id and trigger_id are both required. The usage context is reasonable but not spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAgentMemoryFileGet Agent Memory FileA
Read-onlyIdempotent
Inspect

Get the contents of a single memory file for an agent.

NameRequiredDescriptionDefault
pathYesRelative path to the memory file, e.g. notes.md or context/customer.md
agent_idYesThe agent's unique identifier

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds no behavioral details beyond that, such as what happens for a missing file, authentication requirements, or whether the returned contents are raw text.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no filler. Every word contributes to identifying the operation and its scope.

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 simple read operation with two required parameters, full schema coverage, and rich annotations, this description is sufficient. The agent knows what the tool does, which agent and file path to provide, and that the operation is safe and idempotent.

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 both parameters are already well documented in the schema. The description only adds the general context of reading a memory file, which does not meaningfully extend the parameter semantics beyond what the schema provides.

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 uses a specific verb ('Get') and a precise resource ('contents of a single memory file for an agent'). The phrase 'single memory file' distinguishes it from sibling listAgentMemoryFiles and related file-content tools, making the tool's scope immediately clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to choose this tool over alternatives such as listAgentMemoryFiles, getFileContent, or getSkillFileContent. The description states what the tool does but provides no context, prerequisites, or exclusions to help an agent decide between related tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAgentSuggestionGet Agent SuggestionA
Read-onlyIdempotent
Inspect

Fetch a single suggestion. Poll this after a 202 from consume: an AOP apply in flight reports payload.apply.state (running/failed); once consumed, applied_revision_id carries the draft revision the change was staged onto.

NameRequiredDescriptionDefault
idYesThe suggestion's unique identifier

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the readOnly/idempotent annotations by explaining the stateful polling behavior: an in-flight AOP apply reports payload.apply.state as running/failed, and once consumed, applied_revision_id carries the staged draft revision. This gives the agent meaningful expectations about response states without an output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loads the core action, and packs the essential state-transition guidance into a compact form. Every phrase earns its place without fluff or repetition of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only fetch with one well-documented parameter, the description supplies the key missing context: when to poll, what states to expect, and what the consumed result means. It is slightly implicit about using the suggestion id returned by consume, but overall it is complete enough for correct invocation.

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?

The input schema has 100% description coverage for the single id parameter, describing it as 'The suggestion's unique identifier.' The tool description adds no new parameter meaning, but the schema already carries that burden, so the baseline score of 3 is appropriate.

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: 'Fetch a single suggestion,' which immediately distinguishes it from list-oriented tools like listAgentSuggestions and from mutating tools like consumeAgentSuggestion. The additional polling context reinforces its specific role in the suggestion lifecycle.

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?

The description gives a clear usage trigger: 'Poll this after a 202 from consume,' telling an agent exactly when to call this tool. It does not explicitly name alternatives or state when-not-to-use, but the context is strong enough to route an agent correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAutomationGet AutomationA
Read-onlyIdempotent
Inspect

Get a single automation with its agent and queue counts, the tab arrangement its detail view navigates by, and links to each tab it has right now.

NameRequiredDescriptionDefault
automation_idYesAutomation ID

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive, so safety is covered. The description earns credit by disclosing the shape of the returned data (counts, tab arrangement, current links) even though there is no output schema to convey it, though it says nothing about not-found behavior or auth requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that packs in the return payload without filler. Slightly dense and backtick-heavy, but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully compensates by describing what comes back, and annotations cover the operation's safety profile. It is essentially complete for a simple read-by-ID tool, with only error/not-found semantics left unspecified.

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?

There is one parameter and schema description coverage is 100%, so the schema fully documents automation_id. The description adds no format or constraint detail beyond what the schema provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Get') and resource ('a single automation') and goes on to enumerate the payload components: agent/queue counts, tab arrangement, and per-tab links. It is clearly distinct from listAutomations, but it does not explicitly differentiate itself from close siblings like getAutomationCurrent or getAutomationTabs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: an agent can infer this fetches one automation by ID, and the 'single' wording implies the list alternative. However, it gives no when-to-use guidance relative to getAutomationCurrent, getAutomationTabs, or getAutomationCurrentFlow, nor any preconditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAutomationCurrentGet Automation CurrentA
Read-onlyIdempotent
Inspect

Get what the automation is set up to do right now: its member agents with the builds that are live, its queues' routing, and the triggers and schedules firing for it. The revision-less counterpart of the revision detail — an automation without revisions is read here. links holds a link to each tab the automation has right now.

NameRequiredDescriptionDefault
automation_idYesAutomation ID

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered. The description adds some output-shape context (that it returns current member agents, queue routing, triggers/schedules, and a `links` map), which goes beyond the annotations but does not address freshness, auth requirements, or scope.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences that are front-loaded with the core purpose and finish with a minor detail about `links`. Generally efficient, though the enumerations are slightly dense and the back-reference to 'revision detail' assumes sibling familiarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read-only tool with rich annotations and no output schema, the description gives adequate coverage of what the returned current state contains. It stops short of describing pagination or the full `links`/tab structure, but the essential invocation context is present.

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% for the single automation_id parameter, so the schema already carries the semantics. The description adds nothing about the identifier beyond what the format/pattern in the schema provides, warranting the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb+resource and enumerates exactly what 'current' means: member agents with live builds, queue routing, and firing triggers/schedules. It differentiates against the revision detail via 'the revision-less counterpart,' though it does not distinguish from the related getAutomation or getAutomationCurrentFlow siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'An automation without revisions is read here' implies a selection condition versus the revision detail, which is useful context. However, it never names an explicit alternative tool to call instead nor states when-not-to-use, leaving the agent to infer routing to getAutomation/getAutomationCurrentFlow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAutomationCurrentFlowGet Automation Current FlowA
Read-onlyIdempotent
Inspect

Get the automation's flow graph as it stands right now: the agents and queues it currently wires together, plus the producer, consumer, and handover edges between them. The revision-less counterpart of the revision flow.

NameRequiredDescriptionDefault
automation_idYesAutomation ID

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds behavioral context beyond that by clarifying the response is the current live graph and describing its structural contents. No contradiction exists between description and annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The first sentence front-loads the primary purpose and result contents; the second sentence adds a useful distinguishing qualifier. Every phrase earns its place.

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 simple read-only tool with one well-documented parameter and no output schema, the description sufficiently explains what the result will contain: a flow graph with agents, queues, and edge types. The annotations cover safety and idempotence, and the revision-flow comparison covers positioning, so nothing essential is missing.

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 coverage is 100%, with the single parameter automation_id already documented by name, type, format, and pattern. The description does not need to add parameter details; baseline 3 is appropriate because the schema carries the semantic weight and no additional parameter nuance is required.

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 states a clear verb ('Get') and a specific resource ('the automation's flow graph'), then defines exactly what that includes: agents, queues, and producer/consumer/handover edges. It also distinguishes itself as 'the revision-less counterpart of the revision flow,' which helps separate it from sibling tools like getAutomation and getRevision.

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?

The phrase 'as it stands right now' and 'revision-less counterpart of the revision flow' provide clear context for when to use this tool: when the current live flow graph is needed rather than a revision-specific view. It does not explicitly name alternative tools, but the revision-flow comparison gives practical routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAutomationReadinessGet Automation ReadinessA
Read-onlyIdempotent
Inspect

What still has to be set up before an automation can run on real work. Call this first for a readiness question ("what do I still need to set up", "is it ready to run", "why isn't it running") and before checking an automation's Connections, Logins or Secrets one by one. Each of items is { key, label, status: ok | missing | broken, detail, link, link_tab } and covers one of: required Policy questions still open, Connections with no working account pinned or that need reconnecting, Logins and Secrets (present or missing, never their values), Queue slots with no Queue linked, Queues with routing off, no Agent or an Agent that is not live yet, what starts it (a Trigger, a Schedule, or Cases added to a routed Queue), the active revision and a pending draft, and whether it is still a demo. While a Module is being set up and its proposal has not been approved, items covers only its setup: required Policy questions, the current process map (setup:process_map) and the automation proposal (setup:automation_proposal), or, when its setup progress is unavailable, one setup item linked to the setup's Get started page, whose approval builds the automation; Connections, Queues and what starts it are checked again once the approved proposal is being built. Lead with what is missing or broken, each with its own link (named by link_tab); never build a link. Quote counts from summary, including connections_to_fix, rather than counting items. ready is null when the caller can't read the Policy; note then says what to tell the user. A Connection only the caller can see counts for the caller. When links_note is present, give no link to the automation at all. Each link is a path in the Duvo web app; give the user the full URL beside it (url, and urls for links).

NameRequiredDescriptionDefault
automation_idYesAutomation ID

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description goes well beyond them: it discloses the special read-scoped mode during Module setup, that `ready` is null when the caller lacks Policy read access, that a Connection visible only to the caller counts for the caller, and that `links_note` suppresses automation links entirely. These are non-obvious edge cases an agent could not infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the 'call this first' instruction are front-loaded, and with no output schema much of the length is justified by response-shape detail (item fields, summary counts, url/urls pairing). However, the middle is a dense run-on catalog that would read far better as a short list, and a few clauses (e.g. the setup-progress fallback) are hard to parse on one pass.

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?

No output schema exists, so the description carries the burden of describing return values, and it does: `items` shape with every field, the enumerated categories it can cover, `summary` counts, `ready` nullability, and the link/url pairing. Combined with the read-only annotations, an agent has what it needs to call this and present results correctly.

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?

There is a single required parameter, `automation_id`, documented at 100% schema coverage as a UUID. The description never discusses it, so the schema does all the work here; that matches the baseline-3 case for high schema coverage with no added parameter meaning.

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?

Opens with a concrete framing: 'What still has to be set up before an automation can run on real work.' That is a specific diagnostic resource rather than a restatement of the name, and it is clearly separated from sibling readers like getAutomation, listConnections, or readAutomationPolicy.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'Call this first for a readiness question' and gives the user phrasings that trigger it, plus a negative rule: use it 'before checking an automation's Connections, Logins or Secrets one by one.' That names both the alternative path and the condition that selects this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getAutomationTabsGet Automation TabsA
Read-onlyIdempotent
Inspect

Get the automation detail view's tab arrangement, plus metadata for the Pulse dashboards pinned into it. Pinned dashboards are filtered to the ones the calling identity may see.

NameRequiredDescriptionDefault
automation_idYesAutomation ID

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive behavior. The description adds one useful behavioral trait beyond those: pinned dashboards are filtered by the calling identity's visibility, which is important context an agent could not infer from the schema or annotations. It does not detail return-value shape, but the most safety-relevant behavior is covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences carry the full purpose: main resource, additional returned data, and an important filtering caveat. It is front-loaded with the primary action and contains no filler.

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 single-parameter, read-only tool, the description covers the input (through schema), the output at a useful level (tab arrangement plus each pinned dashboard's metadata), and a visibility filter that affects the result set. No output schema exists, but the high-level return contract is sufficient for an agent to select and invoke the tool correctly.

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 coverage is 100% for the single required automation_id parameter, which already documents its type, format, and meaning. The description adds no param-specific syntax or context, so it warrants the baseline 3 rather than more.

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 names a precise verb-resource pair: it retrieves the automation detail view's tab arrangement plus metadata for pinned Pulse dashboards. It also adds a distinguishing scoping detail (dashboards are filtered by what the caller may see), which separates it from generic getAutomation or listPulseDashboards calls.

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?

The description clearly communicates what this tool returns, so an agent can infer it is the right choice when it needs automation detail tab layout or pinned Pulse dashboard metadata. It does not explicitly identify sibling alternatives or state when not to use it, but the content is specific enough to avoid obvious confusion.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getBatchQueueStatsGet Batch Queue StatsA
Read-onlyIdempotent
Inspect

Get case status counts for many Queues in ONE call. Use this after listQueues whenever you need per-Queue counts — cases waiting on a human, needing review, pending, failed — instead of calling listCases or searchCases once per Queue. Results are keyed by Queue ID and include zero counts for Queues with no matching cases; Queue IDs from other teams are silently dropped. For a count on a single Queue with richer filters, listCases with count_only=true is the alternative.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
queue_idsYesComma-separated Queue IDs to aggregate. Include 1 to 100 IDs from the team in the URL.
created_at_toNoExclusive case creation upper bound. Use an ISO 8601 timestamp or a relative duration such as 7d or 12h. Omit it for no upper bound.
created_at_fromNoInclusive case creation lower bound. Use an ISO 8601 timestamp or a relative duration such as 7d or 12h. Omit it for no lower bound.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent/destructive annotations, the description discloses important behaviors: results are keyed by Queue ID, Queues with no matches get zero counts, and Queue IDs from other teams are silently dropped. This prevents an agent from assuming errors or missing results in those cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each carrying distinct value: what it does, when to use it, what the results look like, and when to use the alternative. The most important scoping fact is front-loaded, and there is no filler or repetition of schema details.

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?

With no output schema present, the description compensates by explaining the response shape: counts keyed by Queue ID, including zero counts. It also covers the auth/team scoping caveat implicitly via the silently-dropped-other-team-IDs note and gives a clear routing alternative, so an agent can select and invoke the tool correctly.

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 coverage is 100%, so the schema already documents queue_ids, team_id, and the date-range parameters. The description adds context about batching and queue scoping, but it does not need to explain parameter formats, and it does not substantially extend the schema's per-parameter meaning.

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, resource, and scope: 'Get case status counts for many Queues in ONE call.' It clearly differentiates itself from siblings like listCases, searchCases, and listQueues by emphasizing batched per-Queue counts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to use this 'after listQueues whenever you need per-Queue counts' instead of calling listCases or searchCases once per Queue. It also names the alternative for single-Queue counts: 'listCases with count_only=true is the alternative.'

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getBuilderRunGet Builder RunB
Read-onlyIdempotent
Inspect

Get the status of a builder run

NameRequiredDescriptionDefault
builder_run_idYesThe builder run identifier.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description adds minimal behavioral context beyond 'status' retrieval. It doesn't mention what status values might be returned, whether the run must be active, or any side effects. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the core action. It is appropriately sized for a simple read operation, though it could add a bit more context without becoming verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with one parameter and full schema coverage, the description is mostly complete. However, the lack of output schema and no mention of what status information is returned leaves some ambiguity. The tool is simple enough that an agent can likely call it correctly, but the description doesn't enrich the context beyond the schema.

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%, with the single parameter builder_run_id fully described as 'The builder run identifier.' The description adds no additional parameter meaning beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Get the status of a builder run' clearly states the verb (get) and resource (builder run status). It distinguishes from siblings like getRun, listRuns, cancelBuilderRun, resumeBuilderRun, and startRun by focusing on status retrieval. However, it doesn't explicitly differentiate from getRun, which could be ambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for checking builder run status but provides no explicit when-to-use guidance or alternatives. Sibling names like getRun and listRuns suggest related tools, but the description doesn't clarify when to choose getBuilderRun over getRun. No exclusions or conditions are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getCaseGet CaseA
Read-onlyIdempotent
Inspect

Get a case by ID. Returns the case, its event history, and every case-approval batch ever created on the case (newest first).

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds useful behavioral detail beyond that by specifying that the response includes the complete event history and every approval batch, with newest-first ordering.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences: the first states the core operation, the second lists the return contents and ordering. Every word earns its place, with no repetition of schema or annotation details.

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 single-parameter read-only getter with rich annotations and full schema coverage, the description is complete. It compensates for the lack of an output schema by naming exactly what the caller receives, including ordering.

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?

The schema fully documents case_id as a UUID unique identifier with 100% coverage. The description only says 'by ID' and does not add new parameter semantics beyond the schema, so the baseline score of 3 is appropriate.

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 names a specific verb ('Get'), a specific resource ('a case by ID'), and the unique return payload: the case, its event history, and all approval batches newest-first. This clearly distinguishes getCase from sibling list/search case tools.

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?

The description makes the usage context clear: call this when you have a case ID and need the full case record with its history and approval batches. It does not explicitly name alternatives like searchCases or listCases, but the by-ID and return-scope wording is enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getCaseAttachmentDownloadUrlGet Case Attachment Download UrlA
Read-onlyIdempotent
Inspect

Mint a short-lived signed URL for one case attachment. disposition=inline serves the file for the in-app viewer; attachment forces a download.

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier
queue_idYesThe queue's unique identifier
dispositionNoattachment
attachment_idYesThe attachment's unique identifier

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish this as a safe, read-only, idempotent operation, so the bar is lower. The description adds valuable behavioral context beyond annotations: the URL is 'short-lived' and 'signed', which implies expiration and authentication requirements. It also explains the behavioral difference between inline serving and forced download, which is not captured in the schema or annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. The primary action is front-loaded, and the disposition clarification is the only additional detail included. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with annotations covering safety and a schema covering parameter semantics, the description is nearly complete. It implies the return value is a URL and discloses the short-lived signed nature. The only minor gap is not specifying the exact response shape or URL expiration duration, but there is no output schema expecting that elaboration.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75%, and the description compensates for the one undocumented parameter ('disposition') by explaining the meaning and effect of both enum values. The other parameters are already well-described in the schema with UUID format and role-specific descriptions, so the marginal value added by the description is appropriately targeted at the gap.

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 states a specific verb ('Mint'), a precise resource ('one case attachment'), and the output ('short-lived signed URL'), which clearly distinguishes it from sibling tools like getFileDownloadUrl or getPulseDashboardAttachmentDownloadUrl. The additional disposition explanation further clarifies the tool's two modes of behavior.

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?

The description gives clear context for when to use the tool: to obtain a download URL for a single case attachment. It also explains how to choose between 'inline' and 'attachment' disposition values, which is practical usage guidance. It does not explicitly name alternative tools or exclusion criteria, but the resource-specific scoping makes the intended use obvious.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getCaseQueueEvalRubricsGet Case Queue Eval RubricsA
Read-onlyIdempotent
Inspect

List a queue's active case-level evaluation rubrics — the Pass/Fail questions a whole case is judged against at settlement. Shows the queue's current version's set (auto-generated from the connected Assignments' AOPs, plus any manually-authored rubrics).

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the description does not need to re-state safety. It adds useful behavioral context by explaining the set is auto-generated from connected Assignments' AOPs plus manually-authored rubrics, and that it reflects the queue's current version.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The core action and resource are front-loaded, and the second sentence adds necessary context about the composition of the rubrics without redundant phrasing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with one parameter and no output schema, the description covers what is returned (active case-level rubrics, current version set, auto-generated plus manual). It could mention edge cases like an empty queue or missing version, but the core context needed to call the tool correctly is present.

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%, with queue_id fully documented as 'The queue's unique identifier.' The description reinforces that the scope is queue-specific but adds no material semantics beyond what the schema already provides, so the baseline of 3 is appropriate.

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 names a specific verb ('List') and a precise resource: a queue's active case-level evaluation rubrics. It further clarifies what those rubrics are (Pass/Fail questions judged at settlement) and distinguishes them from general eval rubrics by the 'case-level' and 'queue' qualifiers.

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?

The description clearly implies when this tool is appropriate: whenever an agent needs a queue's case-level eval rubrics. It does not explicitly name alternative tools like getEvalRubrics or createCaseQueueEvalRubric, nor does it state when not to use it, but the context is clear enough for an agent to select it correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityArtifactChatMessagesGet Clarity Artifact Chat MessagesA
Read-onlyIdempotent
Inspect

Load the latest artifact-chat messages for one active conversation, returned oldest-first.

NameRequiredDescriptionDefault
process_idYesThe Clarity process id
conversation_idYesThe artifact-chat conversation id

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds meaningful behavioral context by specifying that it returns the latest messages and orders them oldest-first, and that the conversation must be active.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence that front-loads the action and includes the key constraints: latest messages, one conversation, active state, and ordering. There is no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity read operation with full schema coverage and safety annotations, the description is sufficient. It names the resource, ordering, and active-conversation requirement; pagination limits and exact response fields are not described but are not critical for correct invocation.

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%, with both process_id and conversation_id already clearly documented. The description adds little parameter-level meaning beyond naming the target conversation, but the schema carries the burden adequately.

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 uses a specific verb ('Load') with a clear resource ('artifact-chat messages') and scope ('one active conversation'). It is easily distinguished from sibling tools like listClarityArtifactChatConversations because it targets messages within a single conversation rather than listing conversations.

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?

The description clearly states the context: loading messages for one active conversation. It does not explicitly name alternative tools or exclusion conditions, but the scope is specific enough that an agent can infer when this tool applies.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityCaptureGet Clarity CaptureA
Read-onlyIdempotent
Inspect

Get a single Clarity v2 capture including full transcript and video transcript. Use this when the process was loaded with captures=lite, or when only one capture's transcript is needed.

NameRequiredDescriptionDefault
capture_idYesThe capture id
process_idYesThe clarity process id

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context by stating the returned capture includes full transcript and video transcript, but it does not disclose other behavior such as response shape or error conditions. This is acceptable given the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The first sentence states the action and returned content, and the second sentence gives concrete usage conditions. Information is front-loaded and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only get-by-id tool with full schema documentation and safety annotations, the description is sufficiently complete. It explains what the tool returns and when to use it, which is enough for an agent to invoke it correctly. A slightly richer statement about the capture relationship to the process could help, but it is not a critical gap.

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%, with both capture_id and process_id documented in the input schema. The description adds no parameter-specific meaning beyond what the schema already provides, so the baseline score of 3 is appropriate.

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 states a specific verb and resource: get a single Clarity v2 capture with full transcript and video transcript. It also signals the scope ('single') and distinguishes this from broader capture/process retrieval tools like listClarityProcessSnapshots or getClarityProcess, even without naming them explicitly.

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?

The description gives explicit conditions for use: when the process was loaded with captures=lite, or when only one capture's transcript is needed. It does not name specific alternative tools or state when not to use it, but the context is clear enough for an agent to select it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityExportGet Clarity ExportC
Read-onlyIdempotent
Inspect

Get a Clarity export run by ID

NameRequiredDescriptionDefault
idYes

TDQS

C2.8/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds no behavioral context beyond the schema; it does not indicate what the response contains, whether a missing ID returns an error, or how this fits into the export workflow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with zero wasted words, and the action 'Get' plus the resource 'Clarity export run' are front-loaded. This is appropriately concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool this is close, but with no output schema and no mention of what is returned or how the ID is obtained, an agent cannot fully predict the call's behavior. It should reference startClarityExport or listActiveClarityExports for context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description needed to compensate for the id parameter's meaning. Saying 'by ID' adds little beyond the schema, and it does not clarify that the ID comes from starting a export or listing active exports.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Get a Clarity export run by ID'), making the lookup intent clear. However, it does not explicitly differentiate this from sibling tools like listActiveClarityExports or getRun, so it falls just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus startClarityExport or listActiveClarityExports. There is also no mention of prerequisites, such as obtaining an export run ID first.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityHierarchyPeopleGet Clarity Hierarchy PeopleA
Read-onlyIdempotent
Inspect

List the people attached to every authorized linked process node in the organization's Process Landscape. Returns a flat list where each person carries nodeId and processId, plus their role, invite status, and capture count. Narrow it with rootId (one subtree), ownerTeamId (one owning team), and userId or search (one person) — an unfiltered organization roster is large enough to be refused by response-size caps. To find the processes where one person has not captured yet, filter to that person and read captureCount per row. truncated is true when the node subtree or any single process roster was capped.

NameRequiredDescriptionDefault
orgIdYes
rootIdNoOnly return rosters for nodes in the subtree under this node
searchNoOnly return rows whose person name or email contains this text, case-insensitively
userIdNoOnly return rows for this platform user, matched on the same resolved identity the roster reports (an email-only row resolves through its organization profile)
ownerTeamIdNoOnly return rosters for processes owned by this team. 404s when the team has no readable Process Landscape

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnly, idempotent, non-destructive), the description explicitly discloses response-size limits and the `truncated` flag behavior, plus the flat result shape. This gives the agent actionable behavioral context about possible partial results and internal cap-causing conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences each earn their place: the purpose, the returned fields, filter guidance with a size-cap warning, a specific use case, and the truncation flag. It is front-loaded and there is no repetition or extraneous detail.

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?

This is a read-only listing tool with no output schema, so the description carries the responsibility for the return shape. It does so completely: the fields, the filters to narrow the result, the warning about response-size refusal, and the meaning of `truncated` are all present, making it sufficient for an agent to call this tool safely.

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 coverage is 80%, so the baseline stays at 3. The description repeats the schema's parameter meanings (rootId -> subtree, ownerTeamId -> team, userId/search -> one person) rather than adding a substantial new layer of meaning for the parameters themselves. The captureCount use case is a usage hint more than deep parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action (list) and resource ('people attached to every authorized linked process node in the organization's Process Landscape') and details the flat output fields. It does not explicitly distinguish itself from sibling tools like listClarityLandscapeNodePeople or listClarityProcessMembers, so it falls short of full differentiation.

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?

Clear context is provided for narrowing results via rootId, ownerTeamId, userId, and search, including a warning that an unfiltered roster may be rejected by response-size caps. It also gives a concrete use case (find processes where a person hasn't captured) but does not exclude alternatives or name when to prefer other tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityOrganizationInterviewGet Clarity Organization InterviewB
Read-onlyIdempotent
Inspect

Load a single organization Clarity interview with transcript

NameRequiredDescriptionDefault
orgIdYes
interviewIdYesThe organization interview ID

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds the behavioral detail that the loaded interview includes its transcript, but discloses nothing else (auth requirements, error behavior, or response shape). This is acceptable for a safe read tool, so a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler, front-loading the action and resource before the payload detail. Every word earns its place; nothing is redundant with the annotations or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-ID get-by-id tool with strong read-only/idempotent annotations and no output schema, the description is nearly sufficient: the required parameters are clearly constrained by the schema, and 'with transcript' hints at what the caller receives. The only modest gap is lack of guidance on listing interviews first or confirming the interview belongs to the org, but neither is critical for a correct call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 50%: interviewId has a schema description, but orgId has none. The tool description does not compensate — it never explains what orgId refers to, how the two identifiers relate, or any additional format/context beyond what the schema already provides. The description adds no real parameter-level meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Load'), a clear resource ('a single organization Clarity interview'), and a key scope qualifier ('single') that implicitly differentiates it from listClarityOrganizationInterviews. It also adds a useful payload detail ('with transcript'). It does not explicitly name sibling alternatives, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The use case is implied — retrieve one specific interview by orgId and interviewId — and the word 'single' hints at the contrast with listing tools, but the description provides no explicit when-to-use guidance, no exclusions, and no named alternative. An agent must infer the routing from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityPortfolioIntelligenceGet Clarity Portfolio IntelligenceB
Read-onlyIdempotent
Inspect

Get portfolio intelligence for the current team

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds the 'current team' scope but does not disclose additional behavioral details such as output freshness, relationship to generated intelligence, or what happens when no intelligence exists. There is no contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, compact sentence with no wasted words. It front-loads the core operation and scope. It could be slightly more informative by clarifying what portfolio intelligence is, but as written it is concise and directly usable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, yet the description does not explain what portfolio intelligence contains or what the agent should expect as a result. It also fails to address the existence of generateClarityPortfolioIntelligence, leaving a key ambiguity about when to retrieve versus generate. The team_id auth details are covered in the schema, but the domain-level context is incomplete.

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%, and the team_id parameter already has a thorough description covering omission, fallback to the API key's team, OAuth usage, and rejection of different teams. The tool description itself adds no parameter-level meaning, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: 'Get portfolio intelligence for the current team.' It is not a tautology and identifies the operation's scope. However, it does not define what 'portfolio intelligence' means or distinguish itself from the sibling tool generateClarityPortfolioIntelligence, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. In particular, there is a sibling tool named generateClarityPortfolioIntelligence, but the description never explains whether the agent should call get versus generate or under what conditions. The team_id schema description offers useful auth context, but this is not guidance about tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityProcessGet Clarity ProcessA
Read-onlyIdempotent
Inspect

Get the v2 read model for a clarity process: the process row (with operational fields like generation_error, generation_progress, generation_started_at, generation_last_activity_at, custom_prompt), its captures, and the lightweight version arrays for both snapshot tabs. The full payload of any specific snapshot is fetched lazily via the unified per-snapshot detail endpoint (GET .../snapshots/:kind/:id); this read model deliberately doesn't carry it so the response stays small.

NameRequiredDescriptionDefault
capturesNoCapture payload mode. `full` (default) embeds each capture's transcript content. `lite` omits `transcript`/`videoTranscript` (returned as null) and relies on the `hasTranscript`/`hasVideoTranscript` flags; fetch content on demand via `GET .../captures/:capture_id`.full
process_idYesThe clarity process id

TDQS

A4.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description aligns with annotations (readOnlyHint, idempotent, non-destructive) and adds transparency by explaining that the response omits full snapshot payloads to keep the response small. This goes beyond the annotations and sets correct expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, well-structured, and covers purpose, scope, and the lazy-loading caveat without redundancy. Every sentence adds value.

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?

Given the simple parameters and the description's detail about the response contents (process row, captures, version arrays), the agent has enough context to use the tool correctly. No output schema is present, but the description fills that gap adequately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the description enriches the 'captures' parameter by explaining the 'full' vs 'lite' modes and their impact on transcript fields. This adds significant meaning beyond the raw enum values.

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 clearly states the tool gets a v2 read model for a clarity process, specifying the contained fields (process row, captures, version arrays). It distinguishes itself from snapshot-specific tools like getClarityProcessSnapshot and getClarityProcessTree.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly mentions that full snapshot payloads are fetched lazily via a unified per-snapshot detail endpoint, guiding agents to use this tool for the lightweight read model rather than trying to retrieve heavy data here. This is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityProcessJoinInfoGet Clarity Process Join InfoC
Read-onlyIdempotent
Inspect

Get information about a clarity interview invite link (public).

NameRequiredDescriptionDefault
tokenYes

TDQS

C2.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds a small behavioral signal with '(public)', implying the invite link is publicly accessible and likely needs no special authentication, but it does not disclose what information is returned or any failure modes. This is modest added context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler or repetition. It is concise, though it is also somewhat under-specified; this keeps it from receiving a 5 because the brevity comes at the cost of useful param and output context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no parameter documentation in the schema, the description carries the burden of explaining what information is returned and what 'token' refers to. It does neither. For a tool that an agent must invoke with a required token, this leaves the agent guessing about both input and output expectations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has one required parameter, 'token', with no description, and schema description coverage is 0%. The tool description does not mention the token at all—neither its meaning, format, nor how to obtain it. The description completely fails to compensate for the schema's lack of parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action and resource: 'Get information about a clarity interview invite link (public).' It is more than a tautology and immediately signals what the tool does, but it does not explicitly distinguish itself from closely related siblings like getClarityProcessInviteLink or acceptClarityProcessJoin.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers no guidance on when to use this tool versus alternatives such as getClarityProcessInviteLink, createClarityInviteLink, or acceptClarityProcessJoin. No context, prerequisites, or exclusions are provided, so the agent must infer usage from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityProcessLandscapeGet Clarity Process LandscapeB
Read-onlyIdempotent
Inspect

Fetch the organization's full process landscape with process summaries, team assignments, and page-level stats

NameRequiredDescriptionDefault
orgIdYes
rootIdNo
teamIdNo

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well covered. The description adds only what data is returned and does not disclose behavioral details such as filtering effects of rootId/teamId, pagination, rate limits, or response shape. It aligns with annotations, so no contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the verb and object, lists meaningful content components, and contains no filler. Every word contributes to communicating the tool's purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and no parameter descriptions, this description is thin. It names high-level return contents but does not explain optional parameters, response structure, or when to use this instead of closely related Clarity tools. An agent could make a basic call with orgId but would lack enough context to correctly use rootId/teamId or understand the full return.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 3 parameters with 0% description coverage, and the description does not compensate. It indirectly associates orgId with 'organization,' but rootId and teamId are left entirely unexplained, forcing the agent to infer their semantics solely from their names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description uses a specific verb 'Fetch' and names the resource 'organization's full process landscape' with concrete contents: process summaries, team assignments, and page-level stats. It is clear, but it does not explicitly distinguish itself from related siblings like getClarityProcessTree, listClarityProcessSummaries, or generateClarityProcessLandscape.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'full process landscape' implies this is used when a broad org-wide view is needed, but no explicit when-to-use or when-not-to-use guidance is provided. The description does not mention alternatives or state exclusions, leaving the choice between this tool and similar Clarity read/list/generate tools to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityProcessSharingGet Clarity Process SharingC
Read-onlyIdempotent
Inspect

Get the sharing status for a clarity process

NameRequiredDescriptionDefault
idYesClarity process ID.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description only repeats the idea of 'Get' without adding behavioral context. It does not describe what 'sharing status' contains, whether it reflects computed or stored state, or how it relates to sharing mutations, so it adds no transparency beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It is concise and easy to parse, though it leans slightly under-specified rather than being a model of informative brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only tool with rich annotations and a fully documented schema, the description is minimally viable for invoking the tool. However, it leaves the meaning of 'sharing status' ambiguous and provides no return-shape or usage context, which would matter given the absence of an output schema.

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?

The schema already provides 100% parameter coverage, including a clear description for the only parameter, id. The tool description adds no additional meaning about the parameter, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear verb (Get) and resource (sharing status for a clarity process), so an agent can tell this is a read operation targeted at sharing information. It does not explicitly distinguish itself from getClarityProcess, getClarityProcessInviteLink, or related siblings, but the phrase 'sharing status' narrows the purpose sufficiently.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance about when to use this tool instead of alternatives such as getClarityProcess, getClarityProcessInviteLink, or updateClarityProcessSharing. There is no mention of complementary tools, exclusions, or typical selection criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityProcessSnapshotGet Clarity Process SnapshotB
Read-onlyIdempotent
Inspect

Fetch the full payload for a Clarity v2 process snapshot of either kind.

NameRequiredDescriptionDefault
kindYesSnapshot kind to list
process_idYesThe clarity process id
snapshot_idYesSnapshot id

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description's 'Fetch' is consistent with those. The description adds that the response is the 'full payload' and that it covers either snapshot kind, but it does not add deeper behavioral context such as authorization needs, snapshot lifecycle constraints, or return format caveats.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no wasted words. It clearly leads with the action and object, and every phrase earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only fetch with fully documented parameters and strong annotations, the description is mostly sufficient. 'Full payload' partially compensates for the lack of an output schema, though a little more context about how the two snapshot kinds differ or when a snapshot_id is valid would make it fully complete.

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 process_id, kind, and snapshot_id are already documented with types, formats, and enums. The description only reinforces the enum via 'of either kind' and adds no new parameter-level meaning, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Fetch') and a specific resource ('full payload for a Clarity v2 process snapshot'), and 'of either kind' maps to the two enum values. It does not explicitly differentiate from sibling tools like listClarityProcessSnapshots or generateClarityProcessSnapshot, but the focus on 'full payload' makes the purpose reasonably clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance about when to use this tool versus related snapshot tools such as listClarityProcessSnapshots, generateClarityProcessSnapshot, or promoteClarityProcessSnapshot. There are no exclusions, prerequisites, or alternative routing instructions, leaving usage entirely to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityProcessTreeGet Clarity Process TreeA
Read-onlyIdempotent
Inspect

Fetch the organization's process tree, or the subtree under rootId. Narrow a large organization with rootId (one subtree) or ownerTeamId (one team's processes) — a whole-organization tree is large enough to be refused by response-size caps

NameRequiredDescriptionDefault
orgIdYes
rootIdNo
ownerTeamIdNoOnly return process nodes owned by this team, plus the folder nodes that carry them. 404s when the team has no readable Process Landscape

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well covered. The description adds important behavioral context about response-size caps and potential refusal for large organizations, which goes beyond the annotations. It also notes that `ownerTeamId` may 404 when the team has no readable Process Landscape, a useful edge case.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the core purpose, then succinctly adds usage guidance for size limits. Every clause adds value, with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tree-fetch tool with no output schema, the description covers the essential decision points (scoping parameters and response-size risk). It lacks detail on the exact structure of the returned tree, but that is likely acceptable given the simple read-only nature. The 404 behavior for `ownerTeamId` is a useful addition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, with only `ownerTeamId` having a schema description. The tool description compensates by explaining the purpose of `rootId` and `ownerTeamId` in narrowing results, adding semantic meaning beyond the schema. For `orgId`, the schema provides its UUID format, which is sufficient.

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 clearly states the tool fetches the organization's process tree, optionally narrowed by `rootId` or `ownerTeamId`. The verb 'Fetch' and resource 'process tree' are specific, and the description distinguishes it from related siblings like `getClarityProcessLandscape` by focusing on the tree structure and scoping.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly advises when to use `rootId` (for one subtree) or `ownerTeamId` (for one team's processes) to avoid response-size refusals. It also warns against fetching the whole organization tree when too large, providing clear context for when to narrow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getClarityTeamSettingsGet Clarity Team SettingsB
Read-onlyIdempotent
Inspect

Get clarity team settings for financial calculations

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already disclose readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds only a purpose clause and no behavioral trait such as authentication requirements, response shape, or how team_id fallback works; that fallback behavior appears only in the parameter schema, not in the description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler. The verb and resource are front-loaded, and the 'for financial calculations' clause adds useful domain context without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, read-only tool with one well-documented optional parameter and strong annotations, the description is close to adequate. However, because there is no output schema, the description leaves the return shape implicit; an agent would benefit from knowing what settings are actually returned, such as rounding rules, currency, or calculation assumptions.

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?

The single optional parameter team_id is fully documented in the input schema, including UUID format, API-key vs OAuth behavior, and rejection of mismatched teams. Since schema description coverage is 100%, the description does not need to add parameter details, and the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), a specific resource ('clarity team settings'), and a domain purpose ('for financial calculations'). This is enough to distinguish it from write tools like updateClarityTeamSettings and from other getters, though it does not explicitly contrast with sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'for financial calculations' gives a weak implied use context, suggesting the tool is relevant when financial calculation settings are needed. However, it does not explicitly say when to use this tool instead of updateClarityTeamSettings, getTeam, or other related getters, and no exclusions or prerequisites are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getConnectionGet ConnectionA
Read-onlyIdempotent
Inspect

Get one of your connections by ID.

NameRequiredDescriptionDefault
connection_idYesConnection ID

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds ownership scoping ('your connections') but does not disclose error behavior, response shape, or distinction from getConnectionCredentials. With annotations present, this is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short, front-loaded sentence with zero filler. Every word earns its place, and the description is appropriately sized for such a simple read operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, read-only, idempotent lookup tool, the description plus schema and annotations covers what an agent needs to invoke it correctly. It could add a note about not returning credentials or about using listConnections for enumeration, but those are optional refinements rather than clear gaps.

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%, and the schema already fully documents connection_id as a required UUID. The description's 'by ID' restates that intent without adding meaning beyond the structured schema, matching the baseline score.

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?

States a specific verb ('Get'), resource ('connections'), and the selection mechanism ('by ID'). This clearly distinguishes it from listConnections and from create/update/delete variants, so an agent can select it confidently.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'by ID' implies this is for retrieving a single known connection, and 'your' scopes it to the user's own connections. However, it does not explicitly mention alternatives like listConnections or when to prefer those, so the guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getConnectionCredentialsGet Connection CredentialsA
Read-onlyIdempotent
Inspect

Get the header keys configured for a connection. Sensitive values (api keys, tokens, passwords) are returned as empty strings — the response only reveals which credential fields are set, never their values.

NameRequiredDescriptionDefault
connection_idYesConnection ID

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds significant behavioral transparency by stating that sensitive values are returned as empty strings, revealing only which fields are set. This goes beyond the readOnlyHint annotation by explaining the exact output behavior. It also implies no side effects, consistent with the idempotent and non-destructive annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that efficiently conveys the purpose and key behavior. It avoids unnecessary details and is well-structured, making it easy for an agent to parse and understand the tool's functionality.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is fairly complete for its scope, explaining both the output (header keys) and the masking of sensitive values. However, it does not mention related tools or provide guidance on when to choose this over getConnection or getCredential, which could be beneficial context. Still, the core information needed for usage is present.

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?

The schema fully describes the parameter with a 'Connection ID' description, and the tool description does not add further semantic detail. The parameter is a straightforward identifier, and the description provides no additional context about how it is used. Since schema coverage is 100%, the baseline score of 3 is appropriate.

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 clearly states the tool's purpose: to get the header keys configured for a connection. It explicitly distinguishes itself by noting that sensitive values are masked, which differentiates it from tools like getConnection that might return full details. The verb 'get' is specific and the resource 'connection' is identified.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool over alternatives like getConnection or getCredential. It implies usage when only header key names are needed, but does not provide explicit guidance or exclusion criteria. The behavioral note about masking sensitive values gives some context, but no direct comparison to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getCredentialGet credential by idB
Read-onlyIdempotent
Inspect

Get a login by id. Returns the encrypted password/otp_secret blobs — only the owner or team members can access it.

NameRequiredDescriptionDefault
idYes
userIdYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only, idempotent, and non-destructive; the description adds that returned blobs are encrypted and access is restricted to owner/team members. This is useful behavioral context beyond the annotations and does not contradict them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, compact sentence that front-loads the operation and includes the return payload and access restriction without filler. Every clause adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only fetch with rich annotations, the description covers the return payload and access restrictions reasonably well. However, it omits what userId is for and does not describe error or not-found behavior, leaving some ambiguity for a three-parameter tool with no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, with team_id documented but userId and id left unexplained. The description adds only the generic phrase 'by id', leaving the required userId's purpose and its relationship to ownership ambiguous.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), resource ('a login'/'credential'), and selection method ('by id'), and previews the sensitive payload. It is clear but does not explicitly differentiate it from siblings like getSecret or listCredentials.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It conveys an access precondition ('only the owner or team members can access it') and implies use when you already have a credential id. However, it does not say when to prefer listCredentials, getSecret, or other credential-related tools, and it offers no exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getEvalRubricsGet Eval RubricsA
Read-onlyIdempotent
Inspect

List the evaluation rubrics a Run is scored against: the platform default rubrics plus the Agent-specific rubrics for a build. Defaults to the Agent's live build; pass build_id to target the revision a specific Run ran against.

NameRequiredDescriptionDefault
agentIdYesThe agent's unique identifier (Assignment ID)
build_idNoReturn rubrics for this specific build (the revision a Run ran against). Defaults to the agent's live build when omitted.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive behavior. The description adds value by disclosing the result composition (default plus Agent-specific rubrics) and the default build-target behavior, which are not inferable from annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the first states the core action and result contents, the second explains the default and the optional parameter. No filler or repetition of schema details.

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 simple, read-only list operation with two fully documented parameters and no output schema, the description covers the action, the returned composition, and the only subtle selection behavior (build default vs explicit build_id). Nothing needed for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents both UUID parameters. The description still adds meaning by explaining the conceptual role of build_id ('target the revision a specific Run ran against') and the default when it is omitted.

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 first sentence names a specific verb ('List') and resource ('evaluation rubrics a Run is scored against'), and clarifies the result composition ('platform default rubrics plus the Agent-specific rubrics for a build'). This distinguishes it from nearby eval/scores/queue-rubric tools and leaves no ambiguity about what is returned.

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?

The description gives concrete usage guidance: omit build_id for the Agent's live build, or pass build_id to target the revision a specific Run ran against. It does not explicitly name sibling alternatives or exclusions, so it falls short of a 5, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getEvalScoresGet Eval ScoresA
Read-onlyIdempotent
Inspect

Aggregate evaluation counts and flag distribution for an Assignment's Jobs since the given timestamp.

NameRequiredDescriptionDefault
scopeNoWhen 'custom', only counts Jobs scored against the target revision's custom rubrics, and only `custom__*` rubric flags. Defaults to 'all' (platform + custom rubrics).
sinceYesISO 8601 timestamp; only Jobs evaluated after this are counted
agentIdYesThe agent's unique identifier (Assignment ID)
revision_idNoTarget a specific Assignment revision instead of the live revision. Only honoured when scope='custom' — non-custom scopes aggregate across all revisions. Defaults to the live revision when omitted.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the primary behavioral aspects. The description adds modest context by describing the aggregation behavior and the time filter, but does not mention any side effects, error conditions, or rate limits beyond what the annotations imply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that states the primary action and key qualifiers without any extraneous text. It front-loads the main intent ('Aggregate evaluation counts and flag distribution') and is appropriately concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of an output schema, the description does not explain the return structure, which could be a gap. However, it does convey the core purpose and the important parameters, and for a read-only aggregation tool, the information provided is likely sufficient for an agent to call it correctly. Omission of return details is the main shortfall.

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 schema already explains each parameter. The description adds little beyond the schema: it mentions 'since the given timestamp' but that is already in the 'since' parameter description. No additional parameter details are provided that are not already present.

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 states a specific verb ('Aggregate') and a clear resource ('evaluation counts and flag distribution for an Assignment's Jobs since the given timestamp'). It clearly differentiates from sibling getters like getEvalRubrics or listRuns by specifying an aggregation over evaluated jobs with a time filter.

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?

The description implies usage context by mentioning the timestamp filter and the aggregation nature, which suggests it is for summary metrics rather than individual records. It also hints at the 'scope' parameter's effect indirectly via the description of revision_id, but it does not explicitly state when to prefer this over alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getFileContentGet File ContentB
Read-onlyIdempotent
Inspect

Get the content of a text file.

NameRequiredDescriptionDefault
pathYesPath of the file relative to the team's storage root
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description is consistent with the annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false) — a read operation — so there is no contradiction. The 'text file' qualifier adds a mild behavioral constraint (binary files aren't supported), but the description otherwise discloses nothing beyond the annotations: no return encoding, no size limits, no missing-file error behavior. With annotations carrying the safety profile, the added value is thin but present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence, 'Get the content of a text file,' with zero wasted words and the verb front-loaded. It's appropriately brief for a simple read tool, though this sentence is also the entire description with no supporting structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 2-parameter read tool, the schema covers all parameters and the annotations cover the safety profile, so the essentials are in place. However, with no output schema, the description doesn't specify how content is returned (raw text vs wrapped/encoded payload), and behavior for missing paths or non-text files is unstated — modest but real gaps for an agent deciding whether and how to invoke the tool.

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 both parameters are already well documented: path is explicitly 'relative to the team's storage root,' and team_id carries detailed API-key-pinning versus OAuth guidance. The tool description itself adds no parameter-level meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get') and resource ('the content of a text file'), making the tool's core function immediately clear. It implicitly distinguishes from siblings like getFileDownloadUrl (URL vs content) and updateFileContent (modify vs read), but it doesn't name alternatives or explicitly call out the text-file-only scope, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives. The description never mentions getFileDownloadUrl for URL needs, updateFileContent for edits, or listFiles for file discovery, and it gives no exclusions for binary files or large files. An agent must infer usage entirely from the tool name and sibling list.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getFileDownloadUrlGet File Download UrlB
Read-onlyIdempotent
Inspect

Generate a signed download URL for a file.

NameRequiredDescriptionDefault
pathYesPath of the file relative to the team's storage root
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile with readOnlyHint=true, idempotentHint=true, and destructiveHint=false, and the description is consistent with those. It adds the useful point that the result is a signed, auth-bearing URL rather than raw file content, but it does not explain signed-URL lifecycle details such as expiration. This is modest added context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler, front-loading the verb and object. Every word earns its place, and it is appropriately terse for a simple URL-generation tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only, idempotent tool with two parameters and 100% schema coverage, the description plus schema is sufficient for correct invocation. It could explicitly mention the return value shape or URL expiration, but 'generate a signed download URL' already communicates the core output expectation. These are minor gaps, not blockers.

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 coverage is 100%, so the baseline applies; path and team_id both have informative descriptions covering storage-root interpretation and API-key/OAuth team behavior. The description itself adds no parameter-level detail, so it neither compensates beyond the schema nor leaves gaps.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Generate a signed download URL') and the resource ('a file'), and 'signed' distinguishes it from generic URL or content-fetch tools. It does not, however, explicitly name sibling tools such as getFileContent or createFileUploadUrl, so differentiation relies on inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance about when to use this tool versus alternatives like getFileContent, listFiles, or createFileUploadUrl, and no excluding conditions are given. The only usage hint is the generic phrase 'for a file,' which leaves selection context to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getLegacyClarityProcessGet Legacy Clarity ProcessA
Read-onlyIdempotent
Inspect

Get a legacy v1 Clarity process with process metadata, generated analysis, automation guidance, generation progress, and captures. Use this for rows from listClarityProcesses where version=1; v2 rows should use getClarityProcess and snapshot detail tools.

NameRequiredDescriptionDefault
idYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly, idempotent, and non-destructive behavior, so the bar for added transparency is lower. The description adds context that this is a 'legacy' v1 process and lists the output categories, which gives some insight into expected behavior. However, it does not mention potential side effects or limitations beyond the legacy tag, so it's not perfectly transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, consisting of two sentences that efficiently communicate purpose and usage. It avoids redundancy and fluff, making it straightforward to parse. The structure is logical: first the action and content, then the usage guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of an output schema, the description does provide a high-level summary of what is returned (metadata, analysis, guidance, progress, captures). It also includes essential usage context for when to apply this tool. However, it does not detail the exact structure of the output or any error conditions, leaving some gaps, but it's sufficient for basic understanding.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema defines only 'id' with no description, and the tool description does not explicitly explain what 'id' represents. While it can be inferred from the context ('rows from listClarityProcesses') that 'id' is the process identifier, this is implicit rather than explicit. With 0% schema description coverage, the tool description should have compensated by clearly stating the parameter's meaning, which it fails to do.

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 clearly states the tool's action ('Get') and resource ('legacy v1 Clarity process'), enumerates the returned content (metadata, analysis, guidance, progress, captures), and explicitly distinguishes it from the v2 counterpart (getClarityProcess). This leaves no ambiguity about the tool's purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit usage criteria: 'Use this for rows from listClarityProcesses where version=1' and directs v2 rows to alternative tools. This makes the when-to-use and when-not-to-use conditions crystal clear, leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getNotificationGet NotificationA
Read-onlyIdempotent
Inspect

Get a single notification by id for the authenticated user. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
idYesThe notification's unique identifier

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds non-obvious runtime behavior beyond those hints: the feature requirement and the 404 when Notification Center is disabled, plus the authenticated-user scoping. This is meaningful behavioral context and does not contradict any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler. The operation is front-loaded, and the second sentence adds only the prerequisite and one relevant error behavior. Every clause earns its place.

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 one-parameter, read-only getter with full schema coverage and strong annotations, the description is complete: it covers purpose, auth scope, and the key 404 edge case. No output schema exists, so return-value detail is not expected, and nothing needed to invoke the tool correctly is missing.

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 coverage is 100%, so the description does not need to compensate for undocumented parameters. The only parameter, id, is already described in the schema with a UUID format, so the description's 'by id' adds no new semantic detail. A baseline 3 is appropriate when the schema carries the parameter documentation.

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: 'Get a single notification by id for the authenticated user.' It distinguishes this from batch, feed, list, and count notification siblings even without naming them, because 'single' and 'by id' clearly signal the lookup operation. It is not a mere restatement of the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use is implied: call this when you have a notification id and need exactly one notification for the current user. It also gives a useful prerequisite and failure mode, the 404 when Notification Center is not enabled. However, it never explicitly contrasts this with alternatives like getNotificationBatch, getNotificationFeed, listNotifications, or getUnreadNotificationCount, so routing guidance is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getNotificationBatchGet Notification BatchA
Read-onlyIdempotent
Inspect

Get a single notification batch by id for the authenticated user, with per-type live-member counts, unread count, and worst severity. Serves cold deep links and sidebar retention for batches the caller can no longer see in the feed. Counts every live member by default; the optional type/severity/minSeverity filters narrow them to matching members only, exactly as the feed narrows a batch row it returns under the same filters. Requires the Notification Center feature; returns 404 when it is not enabled for the team, the batch does not exist, it belongs to another recipient/team, or no live member matches the given filters.

NameRequiredDescriptionDefault
idYesThe notification batch's unique identifier
typeNoCount only live members of this type. Omit to count every live member.
agentsNoWhen 'mine', 404 unless the batch's agent is one the authenticated user created. Pass it alongside the feed's My agents filter so a retained batch cannot come back narrowed on type and severity but not on ownership.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
severityNoCount only live members with exactly this severity. Mutually exclusive with minSeverity. One of: info, warning, critical, success.
minSeverityNoCount only live members at or above this urgency. Least to most urgent: success < info < warning < critical. Mutually exclusive with severity.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond the readOnly/idempotent annotations: default counting of every live member, filter-narrowing semantics matching the feed, the Notification Center feature requirement, and the exact conditions that produce a 404. This is exactly the kind of context an agent needs before calling a retrieval tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four dense sentences, front-loaded with purpose and return data, followed by use case, filter behavior, and error conditions. No sentence is redundant, and complexity justifies the length.

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?

Given six parameters, rich enum-backed schema, and no output schema, the description covers purpose, return fields, filtering behavior, feature gating, and 404 cases. An agent has enough information to call it correctly without opening the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds cross-tool meaning by explaining that type/severity/minSeverity filters narrow counts exactly as the feed narrows a batch row, and that counts default to every live member, but it does not add much beyond the detailed schema for agents/team_id.

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?

States a specific verb and resource: get a single notification batch by id, and specifies the returned data (per-type live-member counts, unread count, worst severity). It is clearly distinguishable from feed/count siblings like getNotificationFeed and getNotificationCounts.

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?

Explains the intended context: cold deep links and sidebar retention for batches no longer visible in the feed. This tells the agent when the tool is useful, though it does not explicitly name getNotification or getNotificationFeed as alternatives for other cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getNotificationCountsGet Notification CountsA
Read-onlyIdempotent
Inspect

Per-type notification counts for the authenticated user's current team. Narrow with unread, important, and with either severity (counts only that exact severity) or minSeverity (counts that urgency and above) — the two are mutually exclusive and a request carrying both is rejected with 400. Pass the same filters the feed is showing, so the counts describe the list the reader would land on. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
agentsNoWhen 'mine', only count notifications for agents the authenticated user created (plus connection_broken, which is always counted), so the counts match a feed filtered the same way.
unreadNoIf true, only count unread notifications.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
severityNoOnly count notifications with exactly this severity, so the counts match a feed filtered the same way. Mutually exclusive with minSeverity.
importantNoIf true, only count notifications pinned to Important for you: unresolved, undismissed connection_broken rows you can reconnect yourself. Use it to size the sidebar alert without paging the list.
minSeverityNoOnly count notifications at or above this urgency, so the counts match a feed filtered the same way. Least to most urgent: success < info < warning < critical. Mutually exclusive with severity.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent annotations, the description discloses additional behavioral traits: it requires the Notification Center feature and returns 404 when not enabled, and it rejects requests with both severity and minSeverity with a 400. It also explains that certain filters (important) have specific counting semantics, adding transparency beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact yet information-dense. Every sentence contributes distinct value: purpose, filter usage, mutual exclusion, feed alignment, and error conditions. It avoids redundancy and is well-structured, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, the description provides a reasonable expectation of the response ('per-type notification counts'). It also covers error cases (400, 404) and parameter relationships. It does not specify the exact response structure (e.g., map vs. list), but this is a minor gap and the tool's purpose is sufficiently clear for invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers 100% of parameters with descriptions, and the tool description reinforces and extends this by linking filters to feed behavior ('so the counts match a feed filtered the same way') and adding usage context for 'important' ('size the sidebar alert without paging the list'). This adds meaningful cross-parameter and real-world semantic value beyond the individual field descriptions.

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 clearly states the tool's function: 'Per-type notification counts for the authenticated user's current team.' It specifies the resource (notification counts), the action (get/count), and the scope (per-type, current team). This unambiguously distinguishes it from feed/list tools and makes its purpose immediately understandable.

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?

The description provides practical guidance on when to use the tool, such as 'Pass the same filters the feed is showing, so the counts describe the list the reader would land on' and 'Use it to size the sidebar alert without paging the list.' It also explains mutual exclusions and error conditions. It does not explicitly name alternative tools, but the context makes appropriate usage clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getNotificationFeedGet Notification FeedA
Read-onlyIdempotent
Inspect

List the notification feed for the authenticated user's current team, most recent activity first. Each item is either an individual notification or a notification batch (a per-agent group of job_issue/eval_issue/job_done/schedule_issue notifications). Filter with type, unread, and either severity (exact match) or minSeverity (threshold; the two are mutually exclusive); paginate with limit/cursor. Either severity filter also narrows a surfaced batch's counts to its qualifying members, and hides a batch with no qualifying live member. The feed is eventually consistent — a batch's counts can lag a concurrent write by one page fetch. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
typeNoOnly return individual notifications of this type and batches with at least one live member of it.
limitNo
agentsNoWhen 'mine', only return notifications for agents the authenticated user created. connection_broken notifications are always returned regardless, because they are not about an agent: a broken connection is only notified to the people who can act on it or escalate it, so filtering by agent authorship would hide it from the reader it was addressed to.
cursorNo
unreadNoIf true, only return unread individual notifications and batches with at least one unread live member.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
severityNoOnly return individual notifications with exactly this severity, and batches with at least one live member of it. A batch's counts then describe only those members. Mutually exclusive with minSeverity. One of: info, warning, critical, success.
minSeverityNoOnly return individual notifications at or above this urgency, and batches with at least one live member at or above it. A batch's counts and worst severity then describe only its members at or above the threshold. Least to most urgent: success < info < warning < critical. Mutually exclusive with severity.

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing that the feed is eventually consistent (batch counts can lag a concurrent write by one page fetch), that severity filters narrow a batch's counts and can hide batches with no qualifying live member, and that a disabled feature yields a 404. These are non-obvious behaviors an agent could not derive from readOnlyHint/idempotentHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose in the first clause, then layers item semantics, filtering rules, consistency caveat, and the feature prerequisite — each sentence carries information. The single dense paragraph is efficient but packs several distinct concerns together, slightly reducing scannability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the prerequisite, error mode, filtering semantics, consistency behavior, and the individual-vs-batch item structure for an 8-parameter tool with no required params. Since there is no output schema, the description could say more about the fields returned by an individual notification or batch, which is the main remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75%, so the baseline is 3, but the description adds real meaning: the mutual exclusivity between severity and minSeverity, that minSeverity is a threshold and severity an exact match, and that either filter also narrows a batch's counts. The limit/cursor and type detail is largely redundant with the schema descriptions, keeping it from a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'List the notification feed for the authenticated user's current team, most recent activity first,' and explains that items are either individual notifications or per-agent batches. It does not, however, distinguish itself from the very close sibling listNotifications or from getNotificationBatch, leaving the agent to infer the difference from the name alone.

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?

Gives clear operational context: how to filter (type, unread, severity vs minSeverity with explicit mutual exclusivity), how to paginate (limit/cursor), and the prerequisite that the Notification Center feature must be enabled with a 404 otherwise. It stops short of naming an alternative tool or saying when not to call it, so it lands at clear-context-but-no-exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getOrgInsightsHeadlineGet Org Insights HeadlineA
Read-onlyIdempotent
Inspect

Get org-wide headline insight KPIs (run totals, success rate, distinct active agents and users) aggregated across every team in the organization. Requires an organization Admin, Executive, or Owner role.

NameRequiredDescriptionDefault
orgIdYesThe organization's unique identifier
endDateNoEnd of the aggregation window (ISO 8601 datetime, exclusive). Defaults to now; clamped to now.
startDateNoStart of the aggregation window (ISO 8601 datetime). Defaults to 30 days ago; clamped to at most 365 days ago.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint=true and destructiveHint=false annotations already covering safety, the description adds useful behavioral context: aggregation across every team in the organization and the role gate. It does not contradict the annotations and provides value beyond the structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler: the first sentence states the action, scope, and output KPIs, and the second states the access requirement. Important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only KPI retrieval tool with no output schema, the description covers what is returned, the aggregation scope, and role requirements, while parameters are fully documented in the schema. It is complete enough for an agent to call correctly, though it could add a pointer to related getOrgInsights* tools for fuller context.

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 schema already documents orgId, startDate, and endDate including defaults and clamping behavior. The description does not add parameter-level detail, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/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: 'Get org-wide headline insight KPIs' and enumerates the exact metrics returned (run totals, success rate, distinct active agents and users), making the core purpose unmistakable. However, it does not explicitly differentiate from sibling tools like getOrgInsightsMetrics or getOrgInsightsUsageChart, which keeps it at a 4 rather than a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The role requirement (Admin, Executive, or Owner) gives a clear prerequisite, and the org-wide scope implies when this tool is appropriate. It does not name alternatives or state when to prefer getOrgInsightsMetrics or getOrgInsightsUsageChart, so usage guidance remains implicit rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getOrgInsightsMetricsGet Org Insights MetricsA
Read-onlyIdempotent
Inspect

Get org-level insights metrics (runs, assignments, schedules) broken down per team across the organization. Requires an organization Admin, Executive, or Owner role.

NameRequiredDescriptionDefault
orgIdYesThe organization's unique identifier
endDateNoEnd of the aggregation window (ISO 8601 datetime). Defaults to now; clamped to now.
startDateNoStart of the aggregation window (ISO 8601 datetime). Defaults to 7 days ago; clamped to at most 365 days ago.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint, idempotentHint, and non-destructive behavior, lowering the burden on the description. The description adds meaningful context by specifying the role requirement and the per-team breakdown behavior, which is not fully captured by annotations. It does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. It front-loads the core purpose and metric categories, then adds the role requirement. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, idempotent tool with three well-documented parameters and no output schema, the description provides sufficient context: what data is included, how it is grouped, and who is allowed to call it. It does not explain the return format, but the annotations and schema already cover safety and parameter details.

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 coverage is 100%, so the input schema already documents orgId, startDate, and endDate with descriptions. The tool description does not add much about parameter semantics beyond reinforcing that these are org-level metrics aggregated per team. Baseline 3 is appropriate because the schema carries the parameter documentation burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb and resource: get org-level insights metrics covering runs, assignments, and schedules, broken down per team. It conveys what the tool does without ambiguity, though it does not explicitly differentiate itself from closely related siblings like getOrgInsightsHeadline or getOrgInsightsUsageChart.

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?

The description provides clear context for when this tool is appropriate: org-level insights metrics aggregated per team across the organization. It also includes an important usage restriction by requiring an Admin, Executive, or Owner role. It does not explicitly discuss alternatives, but the context is strong enough for an agent to select this tool for org-wide metrics.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getOrgInsightsUsageChartGet Org Insights Usage ChartA
Read-onlyIdempotent
Inspect

Get org-level run-volume buckets (scheduled vs on-demand) at day/week/month granularity across the organization. Requires an organization Admin, Executive, or Owner role.

NameRequiredDescriptionDefault
orgIdYesThe organization's unique identifier
endDateYesEnd of the chart window (ISO 8601 datetime). Clamped to now.
timezoneNoIANA timezone for bucket boundaries (e.g. America/New_York). Defaults to UTC.
startDateYesStart of the chart window (ISO 8601 datetime). Clamped to at most 365 days ago.
granularityYesBucket size: day, week, or month

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive behavior. The description adds role requirements and clarifies the data scope, but does not mention any side effects (none exist) or return format, which is acceptable given the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that immediately conveys the tool's purpose without unnecessary fluff, effectively front-loading the key information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool without an output schema, the description provides the essential context (role, data type, granularity). It does not elaborate on return formatting, but that is not critical for correct usage.

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 descriptions cover all parameters (100% coverage) with clear explanations for orgId, startDate, endDate, timezone, and granularity. The description does not add extra parameter-specific details beyond the schema, but the baseline is adequate.

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 clearly states the tool retrieves run-level usage buckets (scheduled vs on-demand) with granularity options, and distinguishes it from sibling insights tools by specifying the exact data returned and required role.

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?

While it does not explicitly mention alternatives, the description implies this is the go-to for org-wide usage charts and notes the role requirement, providing sufficient guidance for typical use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getProfileGet ProfileA
Read-onlyIdempotent
Inspect

Get the profile of the authenticated user (the owner of the API key).

NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds useful context about authentication scope ('the owner of the API key') but does not describe the return shape or any additional behavior, though none is strictly necessary.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single clear sentence with no wasted words. The key information—what is returned and whose profile—is front-loaded and immediately actionable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless read-only getter, the description sufficiently explains the target resource and authentication context. It does not describe the profile fields returned, but since there is no output schema and invocation requires no inputs, the description is adequate for correct tool use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema leaves nothing undocumented. The description adds no parameter details, but none are needed; the baseline of 4 applies for a parameterless tool.

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 states a specific verb ('get') and resource ('profile of the authenticated user'), and clarifies that the subject is the API key owner. This clearly distinguishes it from other getters like getTeam or getAgent, which target different entities.

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?

The description gives clear context: this tool is for the authenticated user's own profile, not any other user or team. It does not explicitly name alternatives, but no closely competing sibling exists for fetching one's own profile, so the usage context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getPulseDashboardGet Pulse DashboardA
Read-onlyIdempotent
Inspect

Get a Duvo Pulse dashboard's metadata and generation status. When status is completed and html_code_present is true, fetch the rendered HTML from GET /artifacts/{artifactId}/render; the conversation is served by GET /artifacts/{artifactId}/messages.

NameRequiredDescriptionDefault
artifactIdYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only, idempotent, non-destructive safety profile. The description adds useful behavioral context by revealing that the tool only returns metadata/status, not the rendered HTML, and by specifying the two follow-up endpoints. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences front-load the core purpose and then provide the conditional follow-up actions. There is no filler or redundant repetition of the schema.

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 one-parameter read-only tool with no output schema, the description names the key result fields (status, html_code_present) and tells the agent what to do next, which is enough to invoke it correctly and handle the result.

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 0%, so the description needs to help with artifactId, but it never explicitly defines it. The path template /artifacts/{artifactId}/... and the phrase 'a Duvo Pulse dashboard' imply artifactId identifies the dashboard, which is sufficient for this single simple UUID parameter but leaves the documentation gap to inference.

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 states a specific verb and resource: retrieving a Duvo Pulse dashboard's metadata and generation status. This clearly separates it from siblings like getPulseDashboardHtml and getPulseDashboardPdf, which fetch rendered artifacts rather than metadata.

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 actionable context by explaining that once status is completed and html_code_present is true, the agent should move to the render endpoint, and that messages come from a separate endpoint. It does not explicitly name sibling tools as alternatives, but the workflow is clear enough to guide selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getPulseDashboardAttachmentDownloadUrlGet Pulse Dashboard Attachment Download UrlA
Read-onlyIdempotent
Inspect

Mint a short-lived presigned URL to download or preview a file attached to a Duvo Pulse dashboard message. Returns 404 once the dashboard's sandbox has expired and the file is gone (about 12 hours).

NameRequiredDescriptionDefault
artifactIdYes
attachmentIdYesThe attachment to mint a download URL for

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only and idempotent, and the description adds meaningful behavioral detail beyond that: the URL is short-lived, and the tool returns 404 after the dashboard sandbox expires in about 12 hours. This gives an agent clear expectations about failure modes and URL lifetime.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with the purpose front-loaded and the expiration/404 behavior as useful secondary detail. There is no filler, repetition, or unnecessary restating of what the schema and annotations already provide.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter URL-minting tool with read-only and idempotent annotations, the description covers purpose, expiry, and the key failure mode. It does not specify how to obtain artifactId/attachmentId or describe the success response, but the return value is strongly implied and no output schema exists.

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 coverage is 50%: attachmentId has a description, artifactId does not. The description provides useful domain context ('dashboard', 'attachment') that helps infer the roles of both parameters, but it does not explicitly explain artifactId or how the two IDs relate, so it only partially compensates for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a precise operation ('Mint a short-lived presigned URL') and a specific resource ('a file attached to a Duvo Pulse dashboard message'), which clearly distinguishes it from generic file download tools. It doesn't explicitly name sibling tools, but the domain scoping is clear.

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?

The phrase 'to download or preview a file attached to a Duvo Pulse dashboard message' establishes a clear use case, and the context is enough to differentiate from upload, export, or dashboard-level download tools. It does not mention alternatives or exclusions, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getPulseDashboardHtmlGet Pulse Dashboard HtmlA
Read-onlyIdempotent
Inspect

Serve a Duvo Pulse dashboard's rendered HTML document (text/html, not JSON). 404 until the first generation turn has produced HTML.

NameRequiredDescriptionDefault
artifactIdYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate read-only, idempotent, and non-destructive behavior. The description adds meaningful non-obvious behavior beyond annotations: the 404-until-generation constraint and the explicit text/html response type. This is valuable context for an agent deciding whether and when to call 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary action is front-loaded, and the 404 caveat is a concise, high-value behavioral detail that earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read-only HTML fetch, the description covers the essential non-obvious details: response content type and the 404-before-generation behavior. It is mostly complete, though explicit sibling routing and a direct explanation of artifactId would make it fully self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema describes artifactId as a required UUID with a pattern but provides no description. The tool description never names or explains the parameter, so with 0% schema description coverage it does not compensate. The phrase 'a Duvo Pulse dashboard's rendered HTML' implies artifactId identifies the dashboard, but this is left to inference.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Serve' and the resource: a Duvo Pulse dashboard's rendered HTML document, with the content type 'text/html, not JSON'. This distinguishes it from JSON-returning getters, but it does not explicitly differentiate it from close siblings like getPulseDashboardVersionHtml or exportPulseDashboardHtml.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a useful temporal usage condition: it will 404 until the first generation turn has produced HTML, implying it should be called after generation. However, it provides no explicit guidance about when to choose this tool over version-specific or export-related siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getPulseDashboardPdfGet Pulse Dashboard PdfA
Read-onlyIdempotent
Inspect

Render a Duvo Pulse dashboard to a PDF document (application/pdf, not JSON). 404 until the first generation turn has produced HTML; 409 for an openui dashboard, whose substrate this exporter cannot render.

NameRequiredDescriptionDefault
themeNolight
artifactIdYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds meaningful behavioral context beyond the annotations: it documents the PDF MIME type, the state-dependent 404, and the 409 for unsupported openui dashboards. This is valuable because it warns the agent about preconditions and limitations that annotations alone do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary purpose is front-loaded, and the second sentence efficiently delivers the only two error conditions an agent needs to know.

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 simple read-only rendering tool with annotations covering safety, the description is complete: it specifies the output format, important error states, and the prerequisite generation condition. The schema handles parameter constraints, so no critical information is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description needed to explain the parameters but does not mention artifactId or theme. The purpose makes artifactId inferable as the dashboard identifier, and the schema provides format constraints, but the description adds no direct parameter meaning.

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 states a specific action and resource ('Render a Duvo Pulse dashboard to a PDF document') and explicitly distinguishes the output type ('application/pdf, not JSON'), which differentiates it from sibling tools like getPulseDashboardHtml. The purpose is immediately clear and unambiguous.

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?

The description provides clear contextual conditions: the tool returns 404 until HTML has been produced and 409 for openui dashboards. This gives useful when/not-when guidance, though it does not explicitly name alternative tools for HTML or other output formats.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getPulseDashboardVersionHtmlGet Pulse Dashboard Version HtmlA
Read-onlyIdempotent
Inspect

Serve a specific version's rendered HTML document for a Duvo Pulse dashboard (text/html, requires edit access).

NameRequiredDescriptionDefault
artifactIdYes
revisionIdYes

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only/idempotent/non-destructive behavior. The description adds two useful facts beyond that: the response is text/html and the caller needs edit access. It doesn't discuss not-found or permission-error behavior, but those are secondary given the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the resource and scope, and no filler. The format and access requirement are packed into parentheticals without bloating.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool, the description covers the resource, MIME type, and access requirement, and annotations cover safety. But the absence of any parameter-level guidance and explicit relationship to sibling HTML/PDF tools leaves minor selection ambiguity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description needed to explicitly map artifactId and revisionId to the dashboard and version. It gives only the general 'specific version's rendered HTML document for a Duvo Pulse dashboard' context, leaving the agent to infer which UUID is which.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Describes a specific action — serving the rendered HTML of a particular Duvo Pulse dashboard version — and adds format/scope ('specific version's', 'text/html'). The qualifier 'specific version's' implicitly separates it from current-version HTML retrieval, though it doesn't name a sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a prerequisite ('requires edit access') and implies the use case of retrieving one revision's HTML, but it doesn't state when to prefer this over getPulseDashboardHtml, getPulseDashboardPdf, or exportPulseDashboardHtml. There is no explicit exclusion or alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getQueueGet QueueC
Read-onlyIdempotent
Inspect

Get a queue by ID.

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds no behavioral detail beyond the annotation coverage, such as return format, not-found behavior, or whether the result includes nested queue configuration.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no wasted words, matching the simplicity of the operation. It is arguably a restatement of the tool name, but it is appropriately sized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read operation with safety annotations, this is nearly sufficient for correct invocation. However, with no output schema, the description does not convey what the response contains or what happens if the queue ID is not found, and it does not route between sibling queue tools.

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?

The input schema covers the single queue_id parameter at 100% and already describes it as the queue's unique identifier. The description adds nothing about the parameter, so the baseline score applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Get') and identifies the resource ('queue') with lookup by ID, so the operation is immediately clear. It does not name sibling tools like listQueues or getQueueAggregationResult, but the basic purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to call this versus listQueues, createQueue, updateQueue, or other queue-related tools. The intended use is implied by the name, but the description provides no explicit context or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getQueueAggregationResultGet Queue Aggregation ResultA
Read-onlyIdempotent
Inspect

Read an aggregation definition's cached result.

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier
definition_idYesThe aggregation definition's identifier

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the safety profile (readOnlyHint=true, idempotentHint=true, destructiveHint=false), so the description's burden is reduced. The description adds one useful behavioral fact beyond annotations: the result is 'cached,' meaning it may be stale relative to a freshly evaluated aggregation. It does not disclose what happens when no cached result exists or whether the result is returned in the same shape as an evaluation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single eight-word sentence with zero filler. The verb is front-loaded, and every word earns its place — 'cached' carries the key semantic weight that separates this from evaluation tools.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter read operation with rich annotations (read-only, idempotent, non-destructive) and no output schema, the description is mostly sufficient. The notable gap is the unresolved relationship to the sibling cluster listingQueueAggregations, evaluateQueueAggregation, and refreshQueueAggregation — an agent must infer when the cached result is the right choice versus those alternatives.

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%: both queue_id and definition_id have type, format, pattern, and descriptive text in the schema. The description adds no new parameter information, so the baseline of 3 applies — the schema carries the full load and does so adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Read') and resource ('an aggregation definition's cached result'), which is clear and unambiguous. The qualifier 'cached' hints at a distinction from the sibling tools evaluateQueueAggregation and refreshQueueAggregation, but it does not explicitly name them, so differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'cached' implies this tool is for retrieving a precomputed result rather than computing or refreshing one, giving an implied usage context. However, there is no explicit when-to-use guidance, no mention of alternatives like evaluateQueueAggregation for fresh results or refreshQueueAggregation to recompute, and no exclusion criteria.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getRevisionGet RevisionC
Read-onlyIdempotent
Inspect

Get a revision by ID.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier
build_idYesThe build's unique identifier

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, which cover the safety profile. The description adds no behavioral context beyond the basic read operation—it does not mention return behavior, error cases, or the composite nature of the identifier.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one short sentence with no filler and the core action is front-loaded. It earns its place without unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should clarify what the returned revision looks like and how agent_id plus build_id map to a revision. The description leaves this ambiguous, and the 'by ID' wording is not helpful given the two required parameters.

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 schema already documents agent_id and build_id clearly. The tool description adds no parameter meaning and its phrase 'by ID' could even mislead an agent into expecting a single revision_id parameter that does not exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the action ('Get') and the resource ('a revision'). However, it does not differentiate revision from related concepts like skill revisions or agent revisions, and 'by ID' is imprecise because the schema requires both agent_id and build_id rather than a single revision ID.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus sibling tools such as listAgentRevisions, getRun, or getSkillRevision. There is no mention of intended context, prerequisites, or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getRevisionBodyGet Revision BodyA
Read-onlyIdempotent
Inspect

Read one section of a revision's config as plain text, in character ranges: the AOP (input) or the code-step program (source). Use it instead of getRevision when the text is large; listAgents with config=light reports each agent's input_chars and source_chars.

NameRequiredDescriptionDefault
lengthNoCharacters to return (1-50000, default 40000). Repeat with a higher offset until offset plus the returned length reaches total_chars.
offsetNoCharacter offset to start reading from (default 0)
sectionYes`input` is an agent step's AOP text; `source` is a code step's program.
agent_idYesThe agent's unique identifier
build_idYesThe revision's unique identifier

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false, and openWorldHint=false, so the safety profile is clear. The description adds operational context: output is plain text, section-specific content is supported, and character ranges are used for large text. It does not add auth or rate-limit details, but annotations reduce the burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the action and followed by usage guidance. Every clause earns its place and there is no redundancy.

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?

With no output schema, the description clearly states that the result is plain text and explains section selection and large-text handling. The schema supplies pagination details, and annotations cover the safety profile, so the definition is complete enough to invoke correctly.

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 schema already explains agent_id, build_id, section, offset, and length. The description restates section meanings and character-range reading but adds little beyond the schema's own definitions, making the baseline 3 appropriate.

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?

States a specific verb 'read' and resource: one section of a revision's config as plain text, naming the input and source sections. It also explicitly distinguishes itself from getRevision by directing large-text use, so an agent can tell it apart from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says to use it instead of getRevision when the text is large, and references listAgents with config=light to obtain input_chars and source_chars. This gives a clear alternative-selection rule and supporting context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getRevisionCaseQueueSetupGet Revision Case Queue SetupA
Read-onlyIdempotent
Inspect

Check that this build's case-queue integration slots are wired up correctly. Returns, per case-queue-producer/consumer slot, how many queues are linked, plus whether any queue is available to bind (scoped to the agent's automation on a migrated team, team-wide otherwise). A slot with linked_queue_count of 0 is attached but points at no queue and will fail at runtime — link a queue with replaceRevisionIntegrationQueues before starting work.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only, idempotent, non-destructive safety profile. The description adds substantial behavioral detail beyond that: per-slot queue counts, queue availability scoping based on team migration state, and the runtime failure implication of zero linked queues.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each earning its place: purpose first, return semantics second, actionable failure scenario third. The description is front-loaded and contains no filler or redundancy.

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?

Even without an output schema, the description communicates the return contents and even names a field (linked_queue_count). For a read-only diagnostic tool with only two required parameters, an agent has enough context to call it correctly and understand the result.

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?

The schema documents agent_id and build_id with 100% coverage, though the field descriptions are only 'Agent ID' and 'Build ID'. The tool description references 'this build's' and 'agent's automation' but does not add meaningful parameter-level semantics beyond what the schema already provides.

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 clearly states the tool's function: checking whether a build's case-queue integration slots are wired correctly. It is specific about the resource (case-queue producer/consumer slots), the verb (Check), and the return shape, which distinguishes it from siblings like listRevisionIntegrationQueues.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says to check before starting work and tells the agent what to do if a slot has linked_queue_count of 0: use replaceRevisionIntegrationQueues to link a queue. This gives both a clear when-to-use condition and a concrete alternative action.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getRunGet RunA
Read-onlyIdempotent
Inspect

Get information about an agent run. Can be polled to check status.

NameRequiredDescriptionDefault
run_idYesThe run's unique identifier

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the tool readOnly, idempotent, and non-destructive. The description adds value by explaining that repeated polling for status is expected, which is a behavioral trait not fully captured by those annotations. It does not describe output fields, but the annotations cover the safety profile well.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler: the first states the tool's purpose, and the second states the polling use case. The key information is front-loaded and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter, read-only, idempotent tool, the description is adequate: an agent knows what the tool does and that it can be polled for status. It does not specify return fields or error behavior, but the low complexity and strong annotations make those omissions acceptable.

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?

The only parameter, run_id, is fully documented in the schema with format, pattern, and description ('The run's unique identifier'), so schema coverage is 100%. The description does not add parameter-level meaning beyond what the schema already provides, so baseline 3 is appropriate.

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 states a specific verb and resource: 'Get information about an agent run.' It also adds a distinguishing behavior, 'Can be polled to check status,' which separates it from listRuns (plural listing) and getRunEvaluation (evaluation-specific). This is clear enough to identify the tool among a very large sibling set.

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?

The sentence 'Can be polled to check status' gives a clear usage context: call this repeatedly to monitor a run's progress. It does not explicitly name alternatives or exclusions, but the intended polling pattern is evident from the description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getRunEvaluationGet Run EvaluationA
Read-onlyIdempotent
Inspect

Get the latest evaluation analysis for a specific agent run (Run).

NameRequiredDescriptionDefault
runIdYesThe run's unique identifier (Run ID)
agentIdYesThe agent's unique identifier (Agent ID)

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the 'latest' recency behavior and run scoping, but does not disclose output shape or absence behavior. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no filler. The main action and resource are front-loaded, and every word contributes meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only getter with complete parameter documentation and safety annotations, the description is adequately complete. It identifies the object type, the required scope, and the recency of the result; the absence of an output schema is partially mitigated by the clear resource description.

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?

Both parameters are fully described in the schema with unique identifiers and UUID formats, so schema coverage is 100%. The description does not add parameter-level meaning beyond what the schema already provides, so baseline 3 applies.

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 names a specific verb ('Get') and a specific resource ('latest evaluation analysis') scoped to a particular agent run. This clearly distinguishes it from related tools like getRun (run metadata) and getEvalScores (evaluation scores).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use when the latest evaluation analysis for a specific run is needed, but it provides no explicit guidance about alternatives or when not to use this tool. There are no exclusions or comparison to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getSecretGet SecretB
Read-onlyIdempotent
Inspect

Get an env-var secret by id. Returns metadata and env var keys; secret values are never exposed.

NameRequiredDescriptionDefault
idYes

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. Beyond that, the description adds valuable context: the tool returns metadata and env var keys, and that values are never exposed — a security guarantee an agent needs before trusting the tool's output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero filler. The verb+resource is front-loaded, and the second sentence earns its place by disclosing both return contents and a critical security property.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter get-by-id tool with no output schema, the description covers the return shape but omits error/not-found behavior, id provenance, and any differentiation from similarly named read tools like getCredential. Adequate but with clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It confirms lookup is 'by id,' but adds nothing about what an env-var secret id is, how to obtain it (e.g., via listSecrets), or what the uuid parameter semantically refers to beyond the schema's format constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Get an env-var secret by id.' The qualifier 'env-var secret' distinguishes it from sibling tools like getCredential and getConnection, though it doesn't name them explicitly. The second sentence sharpens scope by defining exactly what is returned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool (when you need secret metadata or env var keys) but gives no explicit selection criteria, no exclusions, and names no alternatives. The 'secret values are never exposed' line is more a behavioral constraint than routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getSkillFileContentGet Skill File ContentB
Read-onlyIdempotent
Inspect

Get the content of a file in a skill.

NameRequiredDescriptionDefault
pathYesRelative path to the file inside the skill, e.g. SKILL.md.
skill_idYesSkill ID.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this a read-only, idempotent, non-destructive operation, so the safety profile is well covered. The description is consistent with those annotations and adds the 'inside a skill' scope, but it does not disclose encoding, error behavior, or how paths are resolved beyond the parameter schema. This is acceptable given the strong annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence with no filler and the action is stated up front. It is slightly redundant with the title, but it is efficient and appropriately sized for a simple read operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter, read-only tool with complete schema documentation, the description is mostly sufficient. However, the lack of any guidance distinguishing it from getSkillRevisionFileContent and other skill-file tools leaves a meaningful gap for an agent selecting among many similar operations.

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%, with both skill_id and path documented, including an example for path. The tool description itself adds no parameter semantics beyond the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Get'), a resource ('file content'), and a domain ('a skill'), so the core operation is clear. It stops short of a 5 because it does not explicitly differentiate the tool from closely related siblings like getFileContent or getSkillRevisionFileContent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to choose this tool over alternatives such as getSkillRevisionFileContent, getFileContent, or listSkillFiles. There is no mention of which skill version is being read or when revision-specific access would be more appropriate, so the agent is left to infer usage from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getSkillRevisionFileContentGet Skill Revision File ContentB
Read-onlyIdempotent
Inspect

Get the content of a text file in a skill revision.

NameRequiredDescriptionDefault
pathYesRelative path to the file inside the revision, e.g. SKILL.md.
skill_revision_idYesSkill revision ID.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate a safe, idempotent, read-only operation, and the description is consistent with them. It adds modest context by specifying that only text file content is returned, but it does not disclose any other behavior such as path constraints, size limits, or error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence with no filler. It names the action, resource, and scope efficiently, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with only two required parameters and a clear schema, the description is largely sufficient. It could be more complete by explicitly routing the agent away from the similar getSkillFileContent tool, but the core calling context is adequately covered.

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 both parameters are already documented in the schema. The description reinforces that the file must be a text file but does not add meaningful per-parameter semantics beyond what the schema provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get the content') and the resource ('a text file in a skill revision'), which is specific enough to convey the tool's core function. It distinguishes itself from generic file tools by scoping to a skill revision, though it does not explicitly contrast with the closely named sibling getSkillFileContent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is for reading files within a specific skill revision, but it gives no explicit guidance on when to choose this tool over alternatives like getSkillFileContent or getFileContent. There is no mention of when not to use it or which sibling handles current-version versus revision-specific files.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getTeamGet TeamA
Read-onlyIdempotent
Inspect

Get a team by ID. The caller must be scoped to the requested team.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds authorization context about team scoping, which is useful behavioral information beyond the annotations. It does not mention error cases like 404 or invalid team access, but the auth constraint is the key extra detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is only two sentences, with the core action front-loaded and no unnecessary words. Every sentence contributes meaningful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only tool with one optional parameter and rich schema annotations, the description is nearly complete. It could explicitly mention the return value shape or not-found behavior, but 'Get a team by ID' sufficiently implies the successful result for an agent.

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%, and the team_id parameter has a detailed explanation of API-key vs OAuth behavior, fallback semantics, and rejection conditions. The tool description itself adds little parameter-level meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action and resource: 'Get a team by ID.' It is distinct from list-style siblings like listMyTeams and listOrgTeams because it specifies fetching a single team by ID, though it does not explicitly name those alternatives.

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?

The description provides useful scoping context: 'The caller must be scoped to the requested team.' The parameter description further clarifies when to omit or pass team_id based on API-key vs OAuth authentication. It does not explicitly mention alternative tools or when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

getUnreadNotificationCountGet Unread Notification CountA
Read-onlyIdempotent
Inspect

Get the unread notification count for the authenticated user's current team. Each notification batch with unread members counts as 1, regardless of its member count. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavior beyond annotations: the feature dependency, the 404 error condition, and the non-obvious counting semantics for notification batches. This gives the agent useful expectations about the operation's behavior and edge cases without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no filler. It front-loads the core purpose, then adds the essential counting rule, and finally the feature prerequisite and error behavior. Every sentence contributes meaningful information that an agent needs to call the tool correctly.

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?

This is a simple tool with one optional parameter and no output schema. The description fully covers what count is returned, how it is calculated, the scope (current team), and a key failure mode (404 when Notification Center is not enabled). No critical information for correct invocation is missing, and the absence of an output schema does not create ambiguity because the return value is a count implied by the tool's name and description.

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?

The schema already covers the only parameter (team_id) with a detailed description including UUID format, fallback behavior, and OAuth guidance, so schema description coverage is 100%. The tool description adds context about 'current team' and counting semantics, but it does not add new parameter-level details beyond what the schema already provides. Baseline 3 is appropriate.

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 states a specific verb ('get'), a specific resource ('unread notification count'), and a clear scope ('for the authenticated user's current team'). It also clarifies the counting unit ('Each notification batch with unread members counts as 1'), which distinguishes this count from a raw member-level or item-level count. This is more specific than the tool name alone and gives an agent a precise understanding of what is returned.

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?

The description provides clear functional context: it targets the authenticated user's current team, and requires the Notification Center feature or it returns 404. This helps an agent decide when the tool is applicable. It does not explicitly name alternatives such as getNotificationCounts or listNotifications, but the usage context is clear enough that an agent can infer when this tool is the intended one.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

hideConfigFieldHide Config FieldA
Destructive
Inspect

Hide a Policy question from the Policy screen, interviews and every agent's context. Nothing is deleted: the answer and its history stay, and the restore operation shows it again. Returns the agents whose live version still reads the field; hiding is never refused because of them. A module template reinstall keeps the field hidden.

NameRequiredDescriptionDefault
field_idYesThe config field's unique identifier
automation_idYesThe automation's unique identifier

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses that hiding is never refused, that affected live agents are returned, that answers/history persist, and that a module template reinstall keeps the field hidden. This is exactly the 'what gets destroyed / what stays' context a mutation tool needs, and the destructiveHint=true annotation is reconciled by the explicit statement that data is retained.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four dense sentences, each contributing new information (scope, non-destructiveness, return value/refusal semantics, persistence). The scope constraint is front-loaded and there is no filler.

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?

With no output schema, the description compensates by explaining the return (the agents whose live version still reads the field) and the persistence/restore semantics. Nothing needed to call this correctly and interpret it is missing.

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% with only two UUID parameters, so the schema already carries full parameter meaning and the description adds none. Baseline 3 is appropriate; no syntax or format detail is added beyond what the schema provides.

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?

States a specific verb (hide) on a specific resource (a Policy/config field), and scopes the effect precisely: Policy screen, interviews, and every agent's context. This cleanly separates it from siblings like removeConfigSection (structural removal) and restoreConfigField (the inverse).

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 clarifies that this is the non-destructive option ('Nothing is deleted... the restore operation shows it again'), which implicitly tells the agent to prefer it over delete when the change may need reversing, and it names the restore sibling. It stops short of an explicit 'use X instead when Y' rule, so it isn't fully routable on guidance alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inviteClarityMeetingNotetakerInvite Clarity Meeting NotetakerBInspect

Invite the in-meeting notetaker bot (Recall.ai) to a live meeting; the recording lands as a 'meeting' capture on the process

NameRequiredDescriptionDefault
idYesThe clarity process ID
joinAtNo
meetingUrlYes
extraCaptureRequestIdNo

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=false, idempotentHint=false and openWorldHint=true. The description adds genuine value by disclosing the external side effect (a third-party Recall.ai bot is dispatched and the resulting recording becomes a 'meeting' capture on the process). It does not cover failure modes, whether the bot joins immediately or at joinAt, or permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence whose clauses each carry information: the action, the third-party dependency, and the resulting artifact. No filler and the action is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter mutation that dispatches an external bot, with no output schema, the description covers the outcome but leaves the joinAt timing semantics and the extraCaptureRequestId linkage unexplained. Adequate but with clear gaps for an agent to call it correctly in all variants.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% — just the required 'id' is documented. The description says nothing about joinAt (presumably scheduling the bot join), meetingUrl, or extraCaptureRequestId, so it fails to compensate for the three undocumented parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (invite the in-meeting notetaker bot) and names the vendor (Recall.ai) plus the outcome: the recording lands as a 'meeting' capture on the process. The phrase 'on the process' implicitly scopes it against the sibling inviteClarityOrganizationNotetaker, but that distinction is never made explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'live meeting' implies the precondition that the meeting must be active or scheduled, which is useful context. However there is no explicit when-to-use guidance and no reference to the closely named alternative inviteClarityOrganizationNotetaker, so the agent must infer which sibling to pick.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inviteClarityOrganizationNotetakerInvite Clarity Organization NotetakerCInspect

Invite the in-meeting notetaker bot (Recall.ai) to a live meeting; the recording lands as an organization Clarity interview

NameRequiredDescriptionDefault
orgIdYes
titleNo
joinAtNo
meetingUrlYes
extraCaptureRequestIdNo

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly=false, openWorld=true, idempotent=false, destructive=false, so the safety profile is covered. The description usefully adds that a third-party bot (Recall.ai) is dispatched and that the artifact produced is an organization Clarity interview, but stays silent on async behavior, join failures, and what happens to the meeting/recording afterwards.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that leads with the action and ends with the consequence; no filler. The trailing clause is slightly cryptic, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a five-parameter mutation with no output schema and no schema descriptions, the definition does not explain what joinAt is for, what extraCaptureRequestId represents, or what a caller gets back after inviting. The outcome clause helps, but the key parameter and lifecycle gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across five parameters, so the description carries the full burden and largely fails it. Only meetingUrl is indirectly implied by "to a live meeting"; title, joinAt, orgId, and especially extraCaptureRequestId are left completely opaque.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (invite) plus resource (in-meeting notetaker bot) plus the concrete outcome (recording becomes an organization Clarity interview), which is more than a restatement of the name. It does not, however, distinguish itself from the near-identical sibling inviteClarityMeetingNotetaker, leaving the agent to guess which invite tool applies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"to a live meeting" implies the precondition that a meeting must be in progress, but there is no explicit when-to-use, no prerequisites (permissions, org context), and no routing between this and inviteClarityMeetingNotetaker. That ambiguity is exactly where guidance was needed and none is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

inviteOrgMemberInvite Org MemberAInspect

Invite a person to an organization you administer, optionally assigning them to a team in that organization. Requires an organization Admin, Executive, or Owner role. You cannot grant a role higher than your own.

NameRequiredDescriptionDefault
roleYes
emailYes
orgIdYesOrganization ID
teamIdNo
sendEmailNoEmail the invitation to the recipient. `false` always suppresses the email. When omitted, the legacy opt-in applies instead: the email is sent only if the deprecated `frontendUrl` is present. Omit both to create the invitation without notifying anyone.
frontendUrlNoDeprecated. Use `sendEmail` instead. Kept because its presence is the legacy opt-in for sending the invitation email; the value never sets the link host, which is always the server's configured frontend URL.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a non-readonly, non-idempotent, non-destructive operation. The description adds useful behavioral constraints about required roles and role hierarchy, but it does not disclose other side effects such as whether an invitation email is sent or whether the invite creates a pending state. The sendEmail/frontendUrl schema descriptions cover email behavior partially.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences with no fluff. The core purpose is front-loaded, and the permission constraints follow naturally without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the essential decision factors: what the tool does, who can use it, and a key role constraint. With no output schema, it could have mentioned the result or side effects more explicitly, but the combination of description and schema provides enough context for correct invocation in most cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 50%, but the tool description adds meaning by clarifying that teamId is optional and by explaining role hierarchy constraints ('You cannot grant a role higher than your own'). The sendEmail and frontendUrl parameters already have detailed schema descriptions, so the description compensates reasonably for the params that lack schema documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Invite a person') and the resource (an organization you administer), plus the optional team assignment. It is specific enough to identify the tool's purpose, though it does not explicitly differentiate from sibling invite tools like createTeamInvite or bulkCreateTeamInvites.

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?

The description gives clear context for when to use the tool: inviting someone to an organization the caller administers. It also provides crucial permission guidance by stating the required roles and the restriction that you cannot grant a role higher than your own, though it does not discuss alternatives or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listActiveClarityExportsList Active Clarity ExportsA
Read-onlyIdempotent
Inspect

List active (queued or running) Clarity export jobs for the current user

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the operation read-only, idempotent, and non-destructive. The description adds non-obvious behavioral context by scoping results to the current user and filtering to queued or running jobs, which is not captured by the annotations or input schema. It does not mention pagination or response details, but for a read-only list this is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly written sentence that front-loads the verb and resource and adds only the necessary status and scope qualifiers. There is no redundancy or filler.

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 simple read-only list operation with one optional, fully documented parameter and safety annotations already provided, the description and schema are sufficient for an agent to invoke the tool correctly. No output schema exists, but the return concept is clear from the name and description.

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%, and the team_id parameter is already thoroughly documented, including API key team pinning, omission behavior, and OAuth usage. The tool description adds no parameter-level detail, so it does not need to compensate for schema gaps.

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 identifies a specific verb ('List'), a specific resource ('Clarity export jobs'), and a clear scope ('for the current user'), while defining 'active' as 'queued or running'. This clearly distinguishes it from sibling tools like startClarityExport and getClarityExport.

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?

The description provides clear context: use this tool when you want to enumerate a user's active export jobs rather than starting a new export or fetching a single export. It does not explicitly name alternative tools or exclusion conditions, but the scope and status qualifier make the intended usage evident.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentCaseTriggersList Agent Case TriggersA
Read-onlyIdempotent
Inspect

List the case triggers configured for an agent. Each trigger automatically dispatches the agent to run cases added to a queue.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered without contradiction. The description adds domain context about triggers dispatching the agent to run queued cases, but does not disclose tool-specific behavior such as result shape, ordering, or pagination.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the main action front-loaded; the second sentence explains the trigger mechanism without redundancy. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read-only list tool with annotations covering side effects, the description is nearly complete: it names the resource, the scope per agent, and the trigger semantics. It could mention the returned list shape or absence of pagination, but nothing critical is missing for an agent to call it correctly.

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% and the only parameter agent_id is already described as the agent's unique identifier. The description adds no parameter-level semantics, so baseline 3 is appropriate.

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?

States a specific verb ('List') and a specific resource ('case triggers configured for an agent'), and differentiates from sibling list tools via the 'case' qualifier (e.g., listAgentTriggers, listAgentTriggerTypes). The added behavior, auto-dispatch on queue addition, clarifies what these triggers are.

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?

The description gives clear context: the tool is for viewing all case triggers belonging to an agent, and explains their queue-dispatch role. It does not explicitly name alternatives like listAgentTriggers or getAgentCaseTrigger or state when not to use them, so it falls short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentFoldersList Agent FoldersB
Read-onlyIdempotent
Inspect

List all agent folders for the authenticated team.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the description adds minimal new behavioral context. It clarifies the scope ('all', 'authenticated team'), but does not disclose output shape, ordering, or pagination. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It conveys the action, resource, and scope in nine words, earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with one optional, well-documented parameter and annotations covering safety, the description and schema together provide enough to call it correctly. A small gap is the lack of any statement about the return value or whether the list is paginated, but this is minor for a list-all tool.

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%, with the team_id parameter already thoroughly documented including auth fallback behavior. The tool description adds no parameter-level detail beyond the schema, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states the specific action 'List', the resource 'agent folders', and the scope 'for the authenticated team'. This clearly identifies the tool's function and distinguishes it from create/update/delete folder siblings, though it does not explicitly name an alternative tool for comparison.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool versus related listing tools such as listAgents or listClarityFolders, or when to omit vs pass team_id. The only context is 'for the authenticated team', which implies a default team but offers no explicit selection criteria or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentMemoryFilesList Agent Memory FilesB
Read-onlyIdempotent
Inspect

List the memory files stored for an agent.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description does not contradict these annotations, but it also adds no additional behavioral context such as whether file contents are included, whether results are paginated, or what metadata is returned.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no redundant words or restatement of the tool name. Every word contributes to explaining what the tool does.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter, read-only listing tool with strong annotations, the description is nearly sufficient. It does not describe the return shape or pagination, and there is no output schema, but an agent can reasonably infer that the tool returns a list of memory file references for the given agent.

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 coverage is 100%, and the only parameter, agent_id, is documented as 'The agent's unique identifier.' The description adds no further meaning beyond the schema, so it meets the baseline but does not enrich parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action and resource: 'List the memory files stored for an agent.' It clearly conveys what the tool does and is specific enough to distinguish it from sibling tools like getAgentMemoryFile or listAgentFolders, though it does not explicitly differentiate itself by name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternatives such as getAgentMemoryFile or other listAgent* tools. It implies the tool lists all memory files for one agent, but it does not state exclusions, prerequisites, or when a sibling would be more appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentRevisionsList Agent RevisionsA
Read-onlyIdempotent
Inspect

List revisions for an agent. Pass config=light to leave each revision's config out of the page and get its sizes instead; read the AOP with getRevisionBody.

NameRequiredDescriptionDefault
limitNoNumber of revisions per page (1-100, default 20)
configNo`full` (default) embeds each revision's config. `light` sets `config` to null and reports its sizes, hash and models in `config_summary`; read the AOP or program text with getRevisionBody. Use `light` unless you need the instructions themselves: a page of revisions can run to millions of characters.
offsetNoNumber of revisions to skip
statusNoOnly revisions with this status. `live` returns the active revision, wherever it falls in the history.
agent_idYesThe agent's unique identifier

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description adds the pointer that config content is omitted under light mode and must be fetched via getRevisionBody, but says nothing about pagination behavior or default page contents beyond what the schema documents. A 3 is appropriate against an already-strong annotation set.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the core operation and followed immediately by the key usage knob. Nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should carry more of the return-shape burden, and it does note that light mode yields sizes instead of full config. Combined with fully documented params and annotations, it's nearly complete, though a note on pagination/default ordering would close the remaining gap.

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% and the config/status enums are thoroughly documented in the schema, including the size tradeoff. The description's parameter content (config=light behavior) duplicates rather than extends the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List revisions for an agent'), and the mention of getRevisionBody implicitly distinguishes it from the singular-read sibling getRevision. It doesn't, however, explicitly contrast itself with the other revision-list siblings, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It recommends `config=light` and routes the caller to getRevisionBody for the AOP, which is a light form of guidance. But it never states when to prefer this listing over getRevision or listSkillRevisions, and the light-vs-full advice largely restates what the schema already says.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentsList AgentsA
Read-onlyIdempotent
Inspect

List agents for your team. Pass config=light to leave each agent's revision config out of the page and get its sizes instead; read the AOP with getRevisionBody.

NameRequiredDescriptionDefault
limitNoNumber of agents per page (1-100, default 20)
configNo`full` (default) embeds each agent's live revision config in `latest_build.config`. `light` sets that to null and reports its sizes, hash and models in `latest_build_config_summary`; read the AOP or program text with getRevisionBody. Use `light` unless you need the instructions themselves: a full page can run to hundreds of thousands of characters.
offsetNoNumber of agents to skip
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
automation_idNoOnly return agents belonging to this automation.
include_schedulesNoInclude the authenticated user's schedules for each agent in the response. Schedules are per-user, so this only returns schedules the current user owns.false

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds useful context that a full page can be very heavy and that light mode substitutes sizes/summaries, but the crucial performance detail ("hundreds of thousands of characters") lives only in the schema, not the description, and no pagination behavior is described.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with the core action, and the config hint and follow-up tool are packed efficiently with no filler. Slightly compressed for a six-parameter tool but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with rich annotations and no output schema, the description covers the main behavioral fork (config mode) and the escape hatch (getRevisionBody). It omits pagination semantics and the team_id rejection rule, but those are fully handled in the schema, so the gap is minor.

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 schema already documents all six parameters, including the config tradeoff and team_id pinning rules. The description only re-touches the config=light idea without adding syntax or semantics beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List agents") plus a scope qualifier ("for your team"), which is enough to distinguish it from the org-scoped sibling listOrgAgents. It stops short of naming that sibling explicitly, so the differentiation still requires the agent to infer scope from the phrase.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives one clear conditional (use config=light when you don't want full revision configs) and points to getRevisionBody as the follow-up for reading actual bodies. However, it offers no guidance on when to prefer this over listOrgAgents, listQueueAgents, or listAgentRevisions, which are the realistic confusable siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentSchedulesList Agent SchedulesA
Read-onlyIdempotent
Inspect

List the schedules you own on an agent. Returns only your own schedules, whoever you are. Callers with an elevated team role can read every member's schedules on the agent, including who created each one, via GET /agents/{agent_id}/schedules/all.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: results are scoped to the caller regardless of identity, and visibility widens with an elevated team role.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the ownership scoping rule front-loaded ahead of the elevated-role exception. Efficient, though the final sentence is dense with the raw endpoint path, which is slightly less readable than naming the sibling tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter list tool with no output schema, the description covers who sees what and what fields the elevated variant adds (creator). It omits return shape and pagination details, but those gaps are minor given the tool's simplicity.

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?

Only one parameter (agent_id) and schema description coverage is 100%, so the schema fully documents it. The description adds no extra meaning about the parameter, which is the expected baseline when the schema does the heavy lifting.

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?

States a specific verb+resource ('List the schedules you own on an agent') and immediately bounds the scope to the caller's own schedules. It also implicitly distinguishes itself from listAllAgentSchedules by describing the elevated-role variant that returns every member's schedules.

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?

Gives clear context for when this tool applies (you own the schedules, or you lack an elevated team role) and points to the broader alternative endpoint for elevated roles. It falls short of naming the sibling tool listAllAgentSchedules explicitly, requiring the agent to map the REST path to the MCP tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentSlackBoundWorkspacesList Slack Workspaces Bound To An AgentA
Read-onlyIdempotent
Inspect

List the Slack workspaces bound to an agent build that you can create channel triggers for. Creating a Slack channel trigger for any other workspace is rejected, so start here to pick a valid slack_team_id and integration_instance_id.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier
build_idYesThe agent build (revision) whose bound connections to list

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds meaningful context beyond annotations: only workspaces bound to the agent build are valid, other workspaces are rejected, and the returned data includes slack_team_id and integration_instance_id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The primary action is front-loaded, and the second sentence provides the critical usage constraint and the IDs to extract. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with two well-documented UUID parameters and comprehensive annotations, the description is largely complete. It explains purpose, validity constraints, and the key output fields needed for downstream trigger creation, though it does not describe the full response shape or pagination behavior.

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 schema already documents both parameters. The description reinforces that build_id selects the relevant agent revision, and it names the identifiers the caller needs to extract from the results, but it does not add substantial parameter-level detail beyond the schema.

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 states a specific verb and resource: listing Slack workspaces bound to an agent build, and ties it to a concrete downstream purpose (creating channel triggers). This clearly distinguishes it from related tools like listAgentSlackTriggers or createAgentSlackTrigger.

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?

The description gives explicit when-to-use guidance: 'start here' before creating a Slack channel trigger, because other workspaces are rejected. It clearly defines the selection condition, though it does not explicitly name sibling alternatives for adjacent operations like listing existing triggers.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentSlackTriggersList Slack Channel TriggersA
Read-onlyIdempotent
Inspect

List the Slack channel triggers you own on an agent (Agent in the Duvo UI), oldest first. Each trigger's filter_config carries the watched channelId, channelName, Slack workspaceId, and matchRule. Capped at 100 triggers per agent.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds valuable behavioral context beyond annotations: ordering ('oldest first'), the 100-trigger cap, and the specific filter_config fields returned (channelId, channelName, workspaceId, matchRule). No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three concise sentences, each contributing useful information: what is listed, what fields are returned, and the limit. The core action is front-loaded, with no filler or redundancy.

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 single-parameter, read-only list tool, this description is complete. It covers scope, ordering, return-relevant fields, and the hard limit. With annotations covering safety/idempotency and the schema covering the parameter, nothing necessary for correct invocation is missing.

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?

The schema already fully documents agent_id with a description and format, so baseline is 3. The description adds minor context by stating the list is per agent and owned by the caller, but it does not need to elaborate further given the high schema coverage.

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 states a specific verb and resource: 'List the Slack channel triggers you own on an agent.' It clearly distinguishes this from generic trigger listings by specifying Slack channel triggers and the ownership scope. The title reinforces the same resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool—when you need to list Slack channel triggers for an agent—through its clear resource scoping. However, it does not explicitly contrast it with related siblings like listAgentTriggers, listAgentTriggerTypes, or createAgentSlackTrigger, nor does it state when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentSuggestionsList Agent SuggestionsA
Read-onlyIdempotent
Inspect

List an Agent's suggestions. status=pending is the inbox; status=history is consumed/dismissed/auto-cleared. Reads lazily auto-clear stale pending items.

NameRequiredDescriptionDefault
limitNo
offsetNo
statusNopending
agent_idYesThe Agent's unique identifier

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds valuable context beyond annotations by disclosing that the read 'lazily auto-clear[s] stale pending items,' which is a non-obvious behavioral trait. It does not contradict the annotations, though the auto-clear wording introduces slight ambiguity about whether actual mutation occurs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no wasted words. The core purpose is front-loaded, followed by the status semantics, and then the behavioral note about lazy auto-clearing. Each sentence contributes distinct information needed for correct invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the key domain semantics (status meanings), the lazy auto-clear behavior, and the annotations cover safety. With no output schema, the return format is not described, but list tools with sibling getAgentSuggestion provide enough context. Minor gap: pagination behavior of limit/offset is not explicitly connected to the list semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% (agent_id documented), but the description compensates for the most semantically important parameter by explaining what the status enum values mean in domain terms ('inbox' vs 'consumed/dismissed/auto-cleared'). limit and offset are conventional pagination parameters that are self-explanatory, and agent_id is covered in the schema.

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+resource pair, 'List an Agent's suggestions,' which clearly distinguishes this from sibling tools like getAgentSuggestion (single retrieval) and listAgents (different entity). It further disambiguates purpose by explaining the two status filter values, making the tool's intent unmistakable.

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?

The description gives concrete guidance on when to use each status value: 'pending is the inbox; history is consumed/dismissed/auto-cleared.' This is actionable context for choosing the right filter. It does not explicitly name alternatives or exclusion conditions, but the status guidance provides sufficient usage direction for a list tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentTriggersList Agent TriggersA
Read-onlyIdempotent
Inspect

List the trigger definitions the authenticated user owns on an agent (Agent in the Duvo UI). Triggers start a Run automatically when an external event fires (e.g. an email arrives or a Linear issue is created).

NameRequiredDescriptionDefault
agentIdYesThe agent's unique identifier

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive behavior. The description adds useful context: only triggers the authenticated user owns are returned, and triggers start Runs on external events such as email arrivals or Linear issue creation. This goes beyond the structured fields without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with the purpose front-loaded; the trigger definition and examples earn their place. There is no filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only list with rich annotations, the description is nearly complete: it names the resource, ownership scoping, and event semantics. It omits an explicit return-shape or pagination note and sibling differentiation, but these are minor for a simple list tool with no output schema.

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?

The input schema has only agentId with a clear description and 100% coverage, so the schema carries the parameter meaning. The description's 'on an agent' loosely maps to agentId but adds no format or nuance beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the verb 'List' and the resource 'trigger definitions the authenticated user owns on an agent,' with a parenthetical clarifying 'Agent' as the Duvo UI entity. It does not explicitly distinguish itself from sibling tools listAgentCaseTriggers or listAgentSlackTriggers, leaving a small ambiguity about whether it returns all trigger types.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool versus listAgentCaseTriggers, listAgentSlackTriggers, or listAgentTriggerTypes. The description explains what a trigger is but not when this generic listing is preferred, so the agent is left to infer routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAgentTriggerTypesList Agent Trigger TypesA
Read-onlyIdempotent
Inspect

List the trigger types available for an agent, grouped by integration. Use the returned integration_slug and trigger_type values when creating a trigger.

NameRequiredDescriptionDefault
agentIdYesThe agent's unique identifier

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds value beyond those annotations by disclosing that results are scoped per agent ('available for an agent') and organized by integration, revealing return-structure traits not present in the structured metadata.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with zero filler. The primary action is front-loaded in the first sentence, and the second delivers actionable downstream guidance (`integration_slug`, `trigger_type`) that directly supports trigger creation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter, read-only, idempotent tool with complete schema coverage and safety annotations, the description is nearly sufficient: it names the key returned fields and their downstream use. The only gap is not explicitly disambiguating this from the crowded sibling set of trigger-related list tools, though 'trigger types' vs. configured triggers makes the distinction inferable.

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% — agentId is fully documented with type, format, pattern, and description, so the schema carries the parameter-documentation burden. The description only marginally reinforces that results are scoped by agentId ('available for an agent') and adds no new parameter-level meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), resource ('trigger types available for an agent'), and result shape ('grouped by integration'). It conveys that this is a reference catalog of available types rather than a list of configured triggers, which differentiates it semantically from siblings like listAgentTriggers and listAgentSlackTriggers, though it does not name them explicitly.

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?

The second sentence tells the agent what to do with the output ('Use the returned `integration_slug` and `trigger_type` values when creating a trigger'), establishing this as a prerequisite lookup before createAgentCaseTrigger, createAgentSlackTrigger, or upsertAgentTrigger. It implies the usage context clearly but provides no explicit when-not-to-use guidance or named alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAllAgentSchedulesList All Agent SchedulesA
Read-onlyIdempotent
Inspect

List every team member's schedules on an agent, including who created each one. Requires an elevated team role; callers without one receive 403 and should use GET /agents/{agent_id}/schedules, which returns only the schedules they own.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds valuable behavioral context around authorization requirements, the 403 outcome, and that the response includes creator information. It could have provided more detail about response shape or pagination, but the read-only annotation lowers that burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences, both information-dense and front-loaded with the core behavior before the fallback guidance. There is no filler or repeated schema content.

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 simple single-parameter read-only tool, the description covers the operation, authorization requirement, error behavior, and the correct alternative for unauthorized callers. Nothing an agent needs to choose and invoke this correctly is missing.

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?

The only parameter, agent_id, is fully described in the schema with type, format, pattern, and a one-line description, giving 100% schema coverage. The tool description does not need to restate the parameter and adds little semantic value beyond the schema.

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 states a specific action and scope: 'List every team member's schedules on an agent, including who created each one.' It also distinguishes itself from the sibling listAgentSchedules by explicitly covering all schedules rather than only owned ones.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when-to-use guidance, requiring an elevated team role, and names the alternative: callers without the role should use `GET /agents/{agent_id}/schedules`, which returns only schedules they own. This fully routes an agent to the correct tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAutomationsList AutomationsA
Read-onlyIdempotent
Inspect

List the team's automations, each with its live agent and queue counts. An automation is the workspace container an agent or queue belongs to on a team that has moved to Automations — its id is what POST /queues and POST /agents need as automation_id.

NameRequiredDescriptionDefault
limitNoNumber of automations per page (1-250, default 250)
offsetNoNumber of automations to skip
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false. The description adds meaningful behavioral context beyond that by stating that results include live agent and queue counts and by explaining the semantic role of an automation id. It does not disclose pagination behavior, but the schema covers the pagination parameters, so the added context is sufficient for a safe read-only list operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences: the first states the action and result shape, the second explains the domain concept and why the returned id matters. There is no filler, and the most actionable information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with no output schema and three fully documented parameters, the description covers the return content (automations with agent and queue counts) and the key domain context (automation_id). It stops slightly short of explicitly stating the full response shape, such as id/name fields, but nothing critical is missing for correct invocation.

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 parameters (limit, offset, team_id) are already fully documented in the schema. The description does not repeat parameter-specific details, and the automation_id explanation applies to the tool's output rather than to any parameter. Baseline 3 is appropriate because the schema carries the parameter burden.

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 uses a specific verb ('List') and resource ('the team's automations') and adds concrete detail: each automation comes with its live agent and queue counts. It also defines what an automation is and distinguishes it from agents/queues as a containing workspace, which differentiates it from sibling tools like listAgents and listQueues.

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?

The description gives clear context for when the tool is useful: it identifies the workspace-container role of an automation and tells the caller that the automation id is required by POST /queues and POST /agents as automation_id. It does not explicitly name alternatives like getAutomation or state when not to use this tool, but the use case is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listAvailableClarityProcessLabelsList Available Clarity Process LabelsC
Read-onlyIdempotent
Inspect

List process tags available for a process.

NameRequiredDescriptionDefault
idYes
limitNo
offsetNo
searchNo

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds only the scoping notion 'for a process' but does not explain what 'available' means, whether it includes already-assigned labels, what the response contains, or how pagination and search behave.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single efficient sentence with no filler or redundancy. It is front-loaded with the action and resource, though its brevity borders on under-specification.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With four parameters, zero schema descriptions, no output schema, and a close sibling tool, the description is too thin to be complete. The meaning of 'available', the role of the process id, and the optional parameters are all left undefined.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description does not compensate. It never explains the required 'id', the optional 'limit', 'offset', or 'search' parameters, leaving the agent without semantic guidance for any of the four inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('process tags available for a process'), which is enough to convey the core action. It does not explicitly distinguish itself from the sibling 'listClarityProcessLabels', so an agent could confuse the two without deeper inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus the closely named sibling 'listClarityProcessLabels' or related label tools like 'assignClarityProcessLabels'. No context or exclusions are provided, leaving the selection entirely to the agent's interpretation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listCaseAttachmentsList Case AttachmentsA
Read-onlyIdempotent
Inspect

List the files attached to a case, oldest first. Includes attachments whose upload failed, so a missing source document is visible rather than silent.

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier
queue_idYesThe queue's unique identifier

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the operation read-only, idempotent, and non-destructive. The description adds valuable non-obvious behavior beyond annotations: results are ordered oldest-first, and failed uploads are included so missing documents are visible. This is meaningful behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences front-load the core purpose and ordering, then add a single high-value behavioral caveat about failed uploads. Every sentence earns its place with no redundancy.

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?

Given the read-only annotations, 100% parameter schema coverage, and straightforward list operation, the description is complete enough. It covers ordering, the unusual inclusion of failed uploads, and aligns with the tool's obvious use case; no output schema exists, so return-shape documentation is not required.

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 coverage is 100% with clear descriptions for both case_id and queue_id, so the baseline of 3 applies. The description adds no extra meaning about the parameters, neither queue_id's role nor any format details beyond what the schema already provides.

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 uses a specific verb ('List') and a precise resource ('files attached to a case'), and adds ordering ('oldest first'). It also distinguishes itself from generic case tools and related attachment operations by calling out failed uploads.

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?

The usage context is clear: call this when you need the files attached to a case, including checking for missing or failed source documents. It does not explicitly name alternatives or when-not-to-use, but the scope statement is specific enough to route an agent correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listCaseLabelsList Case LabelsA
Read-onlyIdempotent
Inspect

List all labels assigned to a case.

NameRequiredDescriptionDefault
limitNoNumber of labels per page (1-1000, default 1000).
offsetNoZero-based offset for pagination.
case_idYesThe case's unique identifier
queue_idYesThe queue's unique identifier

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already disclose readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds the case-scoping behavior but does not mention pagination behavior despite the limit and offset parameters and the word "all" implying a complete result set. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single short sentence with no filler, clearly front-loading the core purpose. Every word contributes to understanding the operation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is relatively simple and the schema covers parameters thoroughly, but the description lacks any mention of pagination or that the result may be limited by the default limit of 1000. With no output schema, "List all labels" could be slightly misleading without explicit note that pagination is controlled by limit/offset.

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 schema already documents all four parameters. The description adds minimal value here; it implies case_id identifies the case but does not elaborate on queue_id's role or the pagination semantics beyond what the schema already provides.

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 is a specific verb+resource statement: "List all labels assigned to a case." It clearly identifies the operation (list), the resource (labels), and the scope (a specific case). This distinguishes it from sibling label-related tools like assignCaseLabels and unlinkCaseLabels, which denote mutations, and listQueueLabels, which targets a different scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies use when you need to retrieve labels for a given case, but it provides no explicit when-to-use guidance or exclusions. It does not name alternatives such as assignCaseLabels, unlinkCaseLabels, or listQueueLabels, leaving the agent to infer selection based solely on the tool name and description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listCaseRunRecentMessagesList Case Run Recent MessagesA
Read-onlyIdempotent
Inspect

Return the latest qualifying messages (assistant text + tool calls) for a Run on a case, newest last. Used to populate the live body of an active Run card in the case Activity timeline.

NameRequiredDescriptionDefault
limitNoMaximum number of qualifying messages to return. Defaults to 3, must be between 1 and 10.
run_idYesThe agent run's unique identifier
case_idYesThe case's unique identifier

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare read-only and idempotent behavior, and the description adds filtering and ordering details but does not disclose any side effects, auth requirements, or rate limits. It adds some behavioral context beyond annotations, but not substantial new transparency about side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, efficiently stating the operation's purpose and its intended use case. There is no redundant or filler content, and the essential information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description provides enough context for an agent to invoke the tool correctly: it specifies the resource, scope, ordering, and even the content type ('assistant text + tool calls'). However, it does not define the exact meaning of 'qualifying' messages, which could lead to ambiguous expectations, and no output schema is provided, leaving return format partially unspecified.

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?

The input schema covers 100% of parameters with descriptive text (case_id, run_id, limit), so the description does not need to add parameter meaning. The baseline score of 3 applies because schema coverage is high and no additional parameter context is provided.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation returns the latest qualifying messages for a run on a case, with a specific ordering (newest last). It also names the resource and scope, but does not explicitly differentiate from the similar sibling listRunMessages, leaving slight ambiguity about 'qualifying' criteria.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear use case ('Used to populate the live body of an active Run card in the case Activity timeline') but does not explicitly state when not to use it or contrast with alternative tools like listRunMessages. The context implies a specific scenario but lacks direct exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listCaseRunsList Case RunsA
Read-onlyIdempotent
Inspect

List Runs (agent runs) that have claimed or received handover of a case, newest first. Capped at 50 ownership events.

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint=true, idempotentHint=true, destructiveHint=false), so the description correctly adds value beyond them: it discloses ordering ('newest first') and the hard limit ('Capped at 50 ownership events'). These are genuinely useful behavioral traits that the annotations do not express. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero wasted tokens. The core purpose is front-loaded, the parenthetical '(agent runs)' disambiguates terminology against sibling listRuns, and the second sentence adds two concrete behavioral facts (ordering, cap). Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, read-only list tool with rich annotations, this is nearly complete: purpose, scope, ordering, and limit are all stated. The only minor gap is that no output schema exists, so the return shape (what fields each run object contains) is left unspecified — but that is a modest omission for a straightforward list operation.

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 schema already fully documents case_id ('The case's unique identifier'). The description adds no parameter-level meaning beyond what the schema provides, which matches the baseline-3 expectation when the schema does the heavy lifting.

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 states a specific verb ('List'), a resource ('Runs (agent runs) that have claimed or received handover of a case'), and scoping criteria. The 'claimed or received handover' phrasing clearly distinguishes this tool from generic siblings like listRuns and listCaseRunRecentMessages, so an agent can tell them apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the usage context — this is the tool to use when you want runs that own or inherited a specific case, versus generic run listings. However, it never explicitly names alternatives (e.g., listRuns for all runs, getRun for a single run) or states when-not-to-use, leaving dispatch partially to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listCasesList CasesA
Read-onlyIdempotent
Inspect

List cases in a queue. Supports status, date-range, free-text, and json_data field filters via query params. Set count_only=true to skip Case row selection and transformation. The normal response shape is returned with cases: [] and the matching total. For label filters, use POST /v2/queues/:queue_id/cases/search.

NameRequiredDescriptionDefault
fieldNoFilter on a field of a typed queue's json_data, as <path>:<operator>[:<value>] (e.g. $.invoice.amount:gte:5000). Repeat the param to require several; all must match, so two comparisons on one path express a range. Operators: equals, notEquals, in, notIn, gt, gte, lt, lte, contains, isSet, isNotSet. in/notIn take a comma-separated list; isSet/isNotSet take no value. A value is typed by shape (5000 is a number, true a boolean, 00123 a string so a leading zero survives). A path the queue's Case schema does not declare is rejected rather than ignored.
limitNoNumber of cases per page (1-100, default 20).
offsetNoZero-based offset for pagination.
searchNoFull-text search across case title and data.
statusNoFilter by one or more status buckets (comma-separated). Values: all, pending, processing, needs_input, postponed, needs_review, resolved, canceled. `processing` covers both a case actively being worked and one waiting on its evaluation.
sort_byNoField to sort by. Default: created_at.created_at
priorityNoFilter by one or more priority levels (comma-separated). Values: none, medium, high.
queue_idYesThe queue's unique identifier
count_onlyNoSkip row selection and enrichment. The normal list response shape is returned with an empty row array and the matching total.false
sort_orderNoSort direction. Default: desc.desc
created_at_toNoReturn only cases created before this ISO-8601 timestamp. The upper bound is exclusive.
updated_at_toNoReturn only cases updated before this ISO-8601 timestamp. The upper bound is exclusive.
issue_severityNoFilter by highest failing rubric severity (comma-separated). Values: critical, medium. Severity is a facet within the issues outcome, so it returns nothing when combined with a status bucket that excludes issues. `low` is not selectable: an all-low verdict is stored as success, so no case carries it.
created_at_fromNoReturn only cases created at or after an ISO-8601 timestamp or a lookback such as 24h or 7d.
updated_at_fromNoReturn only cases updated at or after an ISO-8601 timestamp or a lookback such as 24h or 7d.
awaiting_my_approvalNoReturn only cases holding an unanswered approval row assigned to you, on the case's own run. Resolved from the authenticated caller, so it names no user: an API key filters as the user who owns it, and a credential with no user behind it is rejected rather than served an empty list. Narrows within needs_input, so it returns nothing alongside a terminal status bucket.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: count_only skips row selection and transformation, and the response shape still returns with an empty cases array plus the matching total.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with the core purpose front-loaded and the count_only behavior immediately after. Slight overlap with the schema's own wording, but no wasted sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema present, the description carries the return-shape burden and does so by describing the count_only response (empty cases array plus total). Combined with the fully documented 16-param schema, an agent has enough to invoke it correctly, though general pagination/return guidance is thin.

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% and the schema itself is unusually detailed, so the baseline is 3. The description only summarizes the filter families generically (status, date-range, free-text, json_data) without adding operator or format detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List cases in a queue") plus the supported filter families. It never names a sibling like searchCases or exportCases directly, though it names the search endpoint as an alternative for label filters, which helps an agent distinguish the two paths.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives one concrete routing rule (use POST /v2/queues/:queue_id/cases/search for label filters) and explains the count_only switch, but says nothing about when to prefer listCases over searchCases or exportCases in general, or about pagination strategy.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityArtifactChatConversationsList Clarity Artifact Chat ConversationsA
Read-onlyIdempotent
Inspect

List the current user's recent non-deleted artifact-chat conversations for a Clarity v2 process and snapshot kind.

NameRequiredDescriptionDefault
process_idYesThe Clarity process id
snapshot_kindYesArtifact kind to list conversations for

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is well covered. The description adds meaningful behavioral context beyond annotations by specifying 'current user's', 'recent', and 'non-deleted', which tell the agent this is a filtered read operation rather than a full dump of all conversations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, no filler, and the core action and resource are front-loaded. The scoping qualifiers ('current user's recent non-deleted', 'Clarity v2 process and snapshot kind') earn their place because they materially narrow what the tool returns.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with two well-documented parameters and safety annotations, the description is largely sufficient. It does not describe the response shape or pagination, but output schema is absent and list-tool return values are generally predictable from the resource name.

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 coverage is 100%, and both process_id and snapshot_kind already have clear descriptions plus an enum for snapshot_kind. The description reinforces that these parameters identify the process and snapshot kind but adds no new semantic detail beyond the schema.

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?

States a specific verb ('List'), a precise resource ('artifact-chat conversations'), and clear scoping ('current user's recent non-deleted', 'for a Clarity v2 process and snapshot kind'). This clearly distinguishes it from siblings like getClarityArtifactChatMessages (messages, not conversations) and deleteClarityArtifactChatConversation (deletion, not listing).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for retrieving conversation summaries for a given process and snapshot kind, but it does not explicitly say when to prefer this over alternatives like getClarityArtifactChatMessages or listClarityProcessSnapshots. It provides clear context about scope (current user, non-deleted, recent) but no exclusions or routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityExtraCaptureRequestsList Clarity Extra Capture RequestsA
Read-onlyIdempotent
Inspect

List active extra-capture requests for a given automation proposal of a Clarity v2 process. The caller is expected to know the proposal id from the V2 read model and skip the call when no proposal exists yet.

NameRequiredDescriptionDefault
limitNoNumber of results per page (1-100, default 20)
offsetNoNumber of results to skip (default 0)
process_idYesThe clarity process id
transformation_proposal_idYesThe automation proposal id

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive behavior, so the description does not need to restate safety. It adds useful behavioral context beyond annotations: the tool returns only 'active' requests, and the caller must already have a proposal id and should avoid calling when no proposal exists. This helps prevent misuse.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two focused sentences with clear front-loading: the first sentence states what the tool does, and the second gives a crucial precondition for correct usage. No filler or redundant restatement of the title or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list operation with well-documented parameters and safety annotations, the description is nearly complete. It covers the main precondition and clarifies the 'active' filter. The only minor gap is that 'extra-capture requests' and the 'V2 read model' are treated as known domain concepts, but this is acceptable given the surrounding tool context.

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 schema already fully documents process_id, transformation_proposal_id, limit, and offset. The description adds domain context by explaining the transformation_proposal_id is for an automation proposal, but it does not provide additional semantic value beyond what the parameter descriptions already convey.

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 states a specific action ('List active extra-capture requests') and a specific resource scope ('for a given automation proposal of a Clarity v2 process'). It clearly differentiates this from siblings like assignClarityExtraCaptureRequest and listClarityLandscapeCaptures by focusing on extra-capture requests tied to an automation proposal.

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?

The description provides practical when-to-call guidance by telling the caller they need to know the proposal id from the V2 read model and should skip the call when no proposal exists yet. It does not name alternatives, but this is a fairly narrow list operation where the main usage risk is calling it prematurely.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityFoldersList Clarity FoldersB
Read-onlyIdempotent
Inspect

List the team's process folders with process and suggestion counts

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is read-only, idempotent, and non-destructive, so the description only needs to add extra behavioral context. It adds that results include process and suggestion counts, but does not mention pagination, ordering, or access limitations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler. It names the verb, resource, scope, and output in one efficient statement.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with one optional parameter and strong annotations, the description is mostly sufficient. It identifies scope and output counts, though the absence of an output schema means return-shape details like pagination or response structure are left unspecified.

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?

The single parameter team_id is already fully described in the schema with UUID format, fallback behavior, and API key versus OAuth semantics. The description itself adds no parameter-level meaning, but 100% schema coverage makes that acceptable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action ('List') and resource ('the team's process folders'), and adds the output detail of process and suggestion counts. It is distinguishable from related tools like listClarityProcesses, though it does not explicitly name or contrast a sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to use this tool versus alternatives, or when not to use it. The team_id parameter description covers authentication behavior but not selection criteria, so the agent must infer usage from the tool name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityInterviewInvitesList Clarity Interview InvitesA
Read-onlyIdempotent
Inspect

List a Clarity process's pending and accepted invitations, newest first, with whether each was accepted, whether it was sent an account-free interview link, and whether the invitee has opened that link or submitted an interview. Paginate with limit and offset; total is the number of invitations. Revoke a pending invitation by passing its id to deleteTeamInvite.

NameRequiredDescriptionDefault
idYesThe Clarity process ID.
limitNoMaximum number of invitations to return, newest first.
offsetNoNumber of invitations to skip, for the next page.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), so the bar is lower. The description adds real context beyond them: it discloses the ordering (newest first), the scope restriction to pending+accepted invitations, and that 'total' represents the invitation count. It does not discuss rate limits or result caps beyond limit's max, but for a read-only list this is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two dense sentences with zero waste; the primary purpose and returned-field list come first, followed by pagination and the revoke cross-reference. Efficient, though the field enumeration makes it slightly long.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description properly compensates by naming the returned fields and the meaning of 'total', which is exactly what an agent needs. Ordering and pagination are covered; nothing critical for correct invocation is missing, though a note on default page size or edge cases would push it higher.

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 id, limit, and offset are already fully documented, making 3 the baseline. The description restates pagination semantics and clarifies that 'total' is the invitation count (a return concept, not a parameter), adding only marginal value beyond the schema.

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?

States a precise verb+resource ('List a Clarity process's pending and accepted invitations') and enumerates the exact fields returned (accepted status, account-free link sent, link opened, interview submitted). An agent can distinguish this from sibling list tools like listTeamInvites or listClarityTeamInterviews at a glance.

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?

Gives clear operational context (newest-first, paginate with limit/offset) and explicitly routes a related action — revoking a pending invitation — to deleteTeamInvite. It lacks an explicit statement of when NOT to use it or which sibling list tools it replaces, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityLandscapeCapturesList Clarity Landscape CapturesA
Read-onlyIdempotent
Inspect

List the organization's Process Landscape captures. By default, only captures eligible to seed new process proposals are returned; excluded captures can be included for inspection.

NameRequiredDescriptionDefault
limitNoNumber of captures to return (1-200, default 100)
orgIdYes
include_excludedNoInclude captures excluded from Process Landscape analysisfalse
includeTranscriptsNoInclude full capture transcripts (large); off by default. Pass the literal string 'true' or 'false' (z.coerce.boolean treats any non-empty value, including 'false', as true).false

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is read-only, idempotent, and non-destructive, so the description does not need to restate those. It adds valuable behavioral context beyond the annotations by explaining the default eligibility filtering and that excluded captures can be included for inspection. This helps the agent predict the tool's default behavior without needing to infer it from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The first sentence front-loads the action and resource, and the second sentence adds the most important behavioral nuance about default filtering and excluded captures. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list operation, the description plus schema and annotations cover the core invocation needs: required orgId, optional pagination, excluded-capture inclusion, and transcript inclusion. It does not describe return shape, ordering, or pagination behavior, but those are not essential for a simple list call, especially given the strong schema documentation.

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 75%, and the schema already documents limit, include_excluded, and includeTranscripts, including the important string 'true'/'false' coercion warning. The tool description does not add parameter-level meaning, but the one less-documented parameter, orgId, is a required UUID that is self-explanatory. This is adequate but not exceptional.

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 states a specific verb ('List') and a specific resource ('the organization's Process Landscape captures'), which clearly identifies the entity being retrieved. It also adds a distinguishing behavioral detail—default filtering to captures eligible to seed new process proposals—that separates it from generic capture or process listing tools.

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?

The description gives clear context for when the tool is appropriate: listing Process Landscape captures, with the default returning only eligible captures and excluded captures available for inspection. It does not explicitly name sibling alternatives or state when not to use the tool, so it falls short of the top score, but the context is clear enough for an agent to understand the intended use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityLandscapeNodeInterviewsList Clarity Landscape Node InterviewsB
Read-onlyIdempotent
Inspect

List Clarity interviews linked to a process folder

NameRequiredDescriptionDefault
limitNoNumber of interviews per page (1-100, default 50)
orgIdYesThe organization ID
nodeIdYesThe clarity process folder node ID
offsetNoNumber of interviews to skip

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile with readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds the scoping behavior that interviews are linked to a process folder, but it does not disclose return format, pagination behavior, or any other operational details beyond what the schema already provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence: it starts with the verb and object, then states the scope. There is no redundant wording or filler; every word contributes to the meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with well-documented parameters and strong annotations, the description covers the essential purpose and scope. It lacks output-shape details and explicit sibling differentiation, but the tool is simple enough that an agent can invoke it correctly with the required parameters.

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?

The input schema has 100% description coverage: orgId, nodeId, limit, and offset all have descriptive text. The tool description adds no additional parameter-level meaning, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), a resource ('Clarity interviews'), and a scope ('linked to a process folder'), which conveys the basic operation. It does not explicitly name sibling alternatives or define what a 'process folder' is in relation to a landscape node, but the purpose is reasonably clear.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance about when to use this tool versus related siblings such as listClarityOrganizationInterviews, listClarityTeamInterviews, or listClarityLandscapeCaptures. The phrase 'linked to a process folder' implies a use case, but there are no explicit selection criteria, exclusions, or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityLandscapeNodePeopleList Clarity Landscape Node PeopleA
Read-onlyIdempotent
Inspect

List the people involved in the process behind one process landscape node. To read the people across the whole landscape in one request, use getClarityHierarchyPeople instead.

NameRequiredDescriptionDefault
orgIdYes
nodeIdYesA process landscape node that is linked to a real process.
teamIdNo

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnlyHint, idempotentHint, and destructiveHint, so safety is well established. The description adds useful scoping context (single node vs whole landscape) but does not describe return shape, pagination, or whether the result includes only directly assigned people or also inherited roles. It adds some context but not rich behavioral detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler. The core purpose is front-loaded in the first sentence, and the alternative tool is presented concisely in the second. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with strong annotations, the description covers the essential scope and sibling differentiation. It does not describe return fields, but there is no output schema and the operation is simple enough that the absence of return-value detail is not a critical gap. Minor param ambiguity holds it back from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, with orgId and teamId undocumented. The description only loosely clarifies nodeId's role as 'one process landscape node' but does not explain what orgId or teamId mean, how they constrain results, or why teamId is optional. With low schema coverage, the description needed to compensate more.

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 uses a specific verb ('List') and resource ('people involved in the process behind one process landscape node'), clearly identifying the scope as a single node. It also distinguishes itself from getClarityHierarchyPeople by explicitly naming the sibling it is not.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool (for one process landscape node) and when to use the alternative (getClarityHierarchyPeople for people across the whole landscape). This is direct, actionable routing guidance with no ambiguity.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityOrganizationInterviewsList Clarity Organization InterviewsB
Read-onlyIdempotent
Inspect

List Clarity interviews across an organization

NameRequiredDescriptionDefault
limitNo
orgIdYes
scopeNo
offsetNo

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the description does not need to restate safety. It adds only the organization-wide scope and gives no detail about pagination, filtering, or response shape, but that is acceptable given the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no redundant words. It is concise, though it sacrifices useful detail for brevity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with a schema that defines defaults and enums, this is minimally adequate. However, it omits the existence of team-scoped listing, pagination behavior, and any indication of what the response contains, so it is not complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description does not explain limit, offset, scope, or orgId. The phrase 'across an organization' hints at orgId, but the description fails to compensate for the undocumented parameters or clarify the team/organization scope enum.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear verb ('List') and names the resource ('Clarity interviews') plus an organization scope. It does not explicitly differentiate from the sibling listClarityTeamInterviews or the singular getClarityOrganizationInterview, so it misses the top tier.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to call this tool instead of listClarityTeamInterviews, getClarityOrganizationInterview, or other interview-related tools. The agent must infer from the name and schema that organization-level listing is intended.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityProcessAssignedLabelsList Clarity Process Assigned LabelsA
Read-onlyIdempotent
Inspect

List process tags on a process.

NameRequiredDescriptionDefault
idYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds process scoping but does not disclose return shape, pagination, or empty-result behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, compact sentence with no filler words. The verb and object are front-loaded, and every word adds meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only tool, the description is minimally adequate, but it is sparse within a large family of similar label-related tools. With no output schema and no sibling differentiation, an agent has limited guidance on expected results or selection among alternatives.

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?

The schema provides no description for the id parameter (0% coverage), and the description only vaguely clarifies that the operation happens 'on a process.' This is enough to infer id is the process identifier, but it does not go further.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), a resource ('process tags/labels'), and a scope ('on a process'). It is clear and not a tautology, though it could better differentiate itself from sibling tools like listClarityProcessLabels and listAvailableClarityProcessLabels.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is used to list labels assigned to a particular process, but it does not explicitly state when to choose this tool over related siblings such as listAvailableClarityProcessLabels or listClarityProcessLabels.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityProcessesList Clarity ProcessesA
Read-onlyIdempotent
Inspect

List Clarity processes for the current team, most recently updated first. Returns lightweight metadata (capture counts, contributors, status) suitable for building a picker; the per-process read model is available via GET /v2/teams/:team_id/clarity-v2/processes/:process_id for v2 rows and GET /v2/teams/:team_id/clarity/processes/:id for legacy v1 rows. Both v1 (legacy) and v2 processes are returned by default; use search, status, and version to narrow discovery. Capped at 100 per page.

NameRequiredDescriptionDefault
limitNoNumber of processes per page (1-100, default 50)
offsetNoNumber of processes to skip (default 0)
searchNoCase-insensitive search across process names
statusNoFilter by process lifecycle status
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
versionNoFilter by Clarity process schema version: 1 legacy, 2 v2

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly/idempotent/safe, and the description adds meaningful behavioral information: default inclusion of both v1 and v2 processes, ordering, return shape ('capture counts, contributors, status'), and the 100-per-page cap. No contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, front-loaded with the action and ordering, and each sentence adds a distinct useful fact: output shape, drill-down alternative, filtering behavior, and pagination cap. No wasted words.

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?

Despite having no output schema, the description discloses the nature of the returned metadata, ordering, default version behavior, filtering options, pagination cap, and how to get the full per-process model. This is enough for an agent to select and invoke the tool correctly.

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 coverage is 100%, and each parameter already has a clear description, including team_id's OAuth nuance and status enum values. The description adds only light extra guidance by grouping search/status/version as discovery filters and mentioning the page cap; the schema does the heavy lifting.

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?

States a specific verb and resource ('List Clarity processes for the current team') plus a concrete ordering ('most recently updated first'). It also distinguishes itself from per-process reads by explicitly saying it returns lightweight picker metadata rather than the full read model.

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?

Gives clear context for when to use it: 'suitable for building a picker', and routes the agent to GET endpoints for the full per-process read model. It also explains that search/status/version narrow discovery and that results are capped at 100 per page. It does not explicitly contrast with the sibling listClarityProcessSummaries tool, so it stops just short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityProcessLabelsList Clarity Process LabelsB
Read-onlyIdempotent
Inspect

List process tags available in an organization.

NameRequiredDescriptionDefault
limitNo
orgIdYes
offsetNo
searchNo

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the read-only nature is established by structured data. The description adds only the organizational scope ('available in an organization'), which is mildly useful but does not disclose pagination, filtering, or what 'available' means.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler, and every word carries purpose. It is concise, though the 'tags' versus 'labels' wording creates minor ambiguity and the terseness contributes to incomplete guidance elsewhere.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with four parameters, no output schema, and no parameter descriptions, this minimal description is not complete. It fails to clarify the search and pagination parameters, what 'available' means, or how this tool relates to similarly named sibling tools, leaving an agent to guess.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for the four parameters, but it only hints at orgId via 'in an organization.' It provides no meaning for limit, offset, or search, leaving the agent without guidance on how pagination and filtering work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), resource ('process tags'), and scope ('in an organization'), making the basic purpose clear. However, it uses 'tags' instead of 'labels' and does nothing to distinguish this tool from the near-identical sibling listAvailableClarityProcessLabels, so it misses the top score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'available in an organization' implies this is the tool to use when retrieving org-scoped process labels, so there is some implicit usage guidance. But there are no explicit when-to-use conditions, no exclusions, and no mention of alternatives such as listClarityProcessAssignedLabels or listAvailableClarityProcessLabels.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityProcessMembersList Clarity Process MembersA
Read-onlyIdempotent
Inspect

List users with accepted access to a clarity process, the people invited who have not accepted yet, and anyone else who has recorded a capture on it

NameRequiredDescriptionDefault
idYesClarity process ID.
contributorsAfterNoCursor from contributorsNextCursor; returns the next page of contributors.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this a safe, idempotent read (readOnlyHint, idempotentHint, destructiveHint=false), so the description need not restate safety. It does add real value by disclosing the composition of the result set, notably that pending invitees and mere capture recorders are included, which an agent could not infer from the name alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted clauses; the purpose leads and the membership categories follow. The trailing three-item enumeration is slightly dense but every element carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description's enumeration of the returned member categories usefully compensates by telling the agent what the result contains. Combined with full schema coverage on inputs and complete read-only annotations, little is missing, though pagination behavior (contributorsAfter/contributorsNextCursor) goes unmentioned.

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% (both 'id' and 'contributorsAfter' are documented in the schema), so the schema carries the parameter burden. The description adds no syntax, format, or pagination-cursor detail beyond it, which is the expected baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('Clarity Process Members') and, unusually, enumerates the three membership categories returned: accepted users, pending invitees, and capture recorders. This makes the tool distinguishable from generic listTeamMembers or listClarityProcessAssignedLabels, though it names no sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the name and description – call it to inspect who is involved with a clarity process. There is no statement of when to prefer it over related tools (e.g. getClarityProcessSharing, listTeamMembers) and no prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityProcessSnapshotsList Clarity Process SnapshotsB
Read-onlyIdempotent
Inspect

List lightweight Clarity v2 process snapshots for one kind.

NameRequiredDescriptionDefault
kindYesSnapshot kind to list
limitNo
offsetNo
process_idYesThe clarity process id

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already disclose read-only, idempotent, non-destructive behavior. The description adds the qualifier 'lightweight', which hints at a reduced payload but does not elaborate on response structure or any side effects. No contradiction exists, but the description contributes minimal behavioral insight beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence that avoids redundancy and directly states the action and object. It is well-structured and easy to parse, with no unnecessary words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has no output schema, and the description does not mention the return format, pagination behavior, or error conditions. It also fails to clarify what 'lightweight' means in terms of data omitted. Given the lack of an output schema, this missing information is critical for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema provides descriptions for 'process_id' and 'kind', but 'limit' and 'offset' lack descriptions despite having defaults and constraints. The tool description does not augment these parameters or explain their role (e.g., pagination). The enum for 'kind' is clear, but the overall parameter semantics are incomplete.

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 clearly states a specific verb ('List') and resource ('Clarity v2 process snapshots') with a scoping qualifier ('for one kind'). It distinguishes this from other list tools by specifying the snapshot type, and the resource is not ambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not provide any guidance on when to use this tool versus alternatives. There are many list-related sibling tools (e.g., listClarityProcesses, listClarityProcessSummaries) and a getClarityProcessSnapshot for retrieving a single snapshot, but no comparison or condition is mentioned. Users must infer the appropriate context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityProcessSummariesList Clarity Process SummariesA
Read-onlyIdempotent
Inspect

Cross-process portfolio digest for every completed Clarity process on the team: per-process summary, SWOT, projected impact, and a step skeleton (role, system, and flow edges) — without step prose or source excerpts. Paginated (default 5, max 10). Use this to answer portfolio-wide questions in one pass; fetch a single process's full detail via getClarityProcessSnapshot only for the few that matter.

NameRequiredDescriptionDefault
limitNoProcesses per page (1-10, default 5). Keeps the response under the MCP output cap.
detailNoskeleton = + per-step role/system/flow edges (default); summary = summary+SWOT+impact only (cheaper, for pure ranking).skeleton
offsetNoProcesses to skip (default 0).
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
include_current_stepsNoInclude the as-is (current) step skeleton too. Default false = proposed (to-be) steps only. Pass the literal string 'true' or 'false' (z.coerce.boolean treats any non-empty value, including 'false', as true).false

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal readOnly, idempotent, and non-destructive behavior. The description adds useful behavioral context beyond that: the tool only covers completed processes, it is paginated with defaults, and it excludes certain content types. This is meaningful added context without contradicting the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is tight and front-loaded: it leads with the tool's core purpose and return contents, then quickly explains pagination and gives the key routing guidance. No sentences are wasted and the most important discriminator is stated early.

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 read-only, no-required-param, paginated list tool, the description is complete: it names the return contents, scoping, pagination behavior, and the correct alternative for single-process detail. The absence of an output schema is compensated by the explicit enumeration of the response fields.

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 schema already documents all parameters well. The description restates pagination defaults that appear in the schema and does not add substantial new meaning to any specific parameter. Baseline 3 is appropriate because the schema carries the burden.

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 states a specific action ('cross-process portfolio digest') and enumerates exactly what it returns: per-process summary, SWOT, projected impact, and a step skeleton. It also distinguishes this tool from getClarityProcessSnapshot, which covers single-process detail, so an agent can select among siblings without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance: use this tool to answer portfolio-wide questions in one pass, and use getClarityProcessSnapshot only for the few processes that need full detail. It also states what this tool intentionally omits (step prose and source excerpts), which tells agents when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityStepFramesList Clarity Step FramesA
Read-onlyIdempotent
Inspect

Return one representative screenshare frame for each current-process step. Explicit frame evidence wins. Otherwise, a timestamped screenshare transcript source selects the closest persisted frame at or after that timestamp, with the closest earlier frame as fallback. Pass window (1-5) to also receive that many neighbouring frames on each side as candidates, for recovering when the selected frame does not show the step. Pass size=thumb for 768px copies that are cheaper to download and inspect. Signed URLs are short-lived and can be null when signing is unavailable.

NameRequiredDescriptionDefault
sizeNofull: the persisted screenshot (1920px wide). thumb: a 768px-wide copy, cheaper to download and to inspect visually; use it to check whether a frame shows the step, then fetch full for the document.full
windowNoNumber of neighbouring persisted frames to return on each side of the selected frame as `candidates` (0-5, default 0). Use to recover when the selected frame does not show the step.
step_idsNoOptional comma-separated step ids to resolve, for example `task-a,task-b` (maximum 100). Omit to resolve every step.
process_idYesThe clarity process id
snapshot_idYesThe current-process snapshot id

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses the frame selection algorithm (explicit evidence, closest at/after timestamp with earlier fallback), the behavior of `window` (neighbouring candidates), and that signed URLs are short-lived and may be null. This is consistent with the read-only and idempotent hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is detailed but each sentence contributes essential information about selection, fallback, and parameter effects. It is slightly longer than necessary but remains focused and free of extraneous content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While there is no output schema, the description explains the return format (representative frames per step, candidates, signed URLs) and the conditions under which URLs may be null. This is sufficient for an agent to understand the result, though a formal output schema would add more precision.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All five parameters are covered in the schema and the description adds meaningful semantics: `window` explains neighbouring frames and candidates, `size` explains full vs thumbnail, `step_ids` explains comma-separated resolution, and `process_id`/`snapshot_id` are clearly identified. The description enhances the schema rather than merely repeating it.

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 clearly states the tool returns one representative screenshare frame per current-process step, with explicit selection logic. It distinguishes itself from other list tools by focusing on step frames and their resolution.

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?

Provides concrete guidance on when to use the `window` and `size` parameters, and explains the fallback behavior when the selected frame does not show the step. While it does not explicitly compare to sibling tools, the context and parameter instructions are sufficient for usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listClarityTeamInterviewsList Clarity Team InterviewsB
Read-onlyIdempotent
Inspect

List team-level Clarity interviews

NameRequiredDescriptionDefault
limitNoNumber of interviews per page (1-100, default 50)
offsetNoNumber of interviews to skip
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds no behavioral context beyond that, but it also does not contradict the annotations. The interesting behavioral nuance about team_id fallback and rejection lives in the schema, not the description, so no extra credit is warranted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero wasted words. It is appropriately terse for a simple list operation, though it is lean enough that some semantic context (what a Clarity interview is) is left to inference.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple paginated list tool with fully-documented optional parameters and annotations covering safety, the definition is largely sufficient. The main gaps are the absence of an output schema and a lack of clarification about the relationship between team-, organization-, and landscape-node interview listings, but these are minor for a straightforward read-only list operation.

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 schema fully documents all three parameters. The description itself adds nothing about parameters, which matches the baseline of 3 when the schema does the heavy lifting. The team_id description is notably rich but counts as structured data, not description value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List team-level Clarity interviews'. The 'team-level' qualifier distinguishes it from closely named siblings like listClarityOrganizationInterviews and listClarityLandscapeNodeInterviews, though it never explicitly names or contrasts them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers no guidance on when to use this tool versus its alternatives. It does not mention the related organization-level or landscape-node interview listing tools, nor any condition that would select one over another. The 'team-level' phrasing implies a scope but provides no actionable routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listConfigFieldsList Config FieldsA
Read-onlyIdempotent
Inspect

Read an automation's module config fields (its Policy), grouped by section in the automation's section order, with each field's current value, default, and fill provenance.

NameRequiredDescriptionDefault
automation_idYesThe automation's unique identifier
include_hiddenNoAlso return the questions a person hid, marked active: false, in their sections, and every empty section a person added, with no fields. Questions the module template retired are never returned. The counts still cover the visible questions only. Defaults to false.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description goes beyond that by disclosing the return shape: grouped by section in section order, each field with current value, default, and fill provenance. It does not address the hidden-field behavior, but that is documented in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence with zero waste, front-loading the resource and then the return structure. Nothing is padded or redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of explaining return values and does so adequately (section grouping, value, default, provenance). Combined with annotations covering the safety profile and full schema coverage, it is nearly complete, missing only hidden-field return behavior which the schema handles.

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 both automation_id and include_hidden (with its enum and detailed semantics) are already fully documented in the schema. The description adds no additional parameter meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Read'), a precise resource ('an automation's module config fields (its Policy)'), and the return grouping. An agent can distinguish this from sibling listConfigSections, which lists sections rather than fields, without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The read-only, list nature implies when to use it, but there is no explicit when-to-use, prerequisite, or named alternative (e.g. listConfigSections or getAutomation) to route the agent. Usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listConfigSectionsList Config SectionsA
Read-onlyIdempotent
Inspect

List the sections of an automation's Policy in display order, empty ones included, each with its key, name, origin and question count. No offset/limit params: this is the automation's whole set of sections.

NameRequiredDescriptionDefault
automation_idYesThe automation's unique identifier

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so the safety profile is covered. The description adds genuinely new behavioral facts: results are in display order and empty sections are included, which an agent cannot infer from the annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, and the core action plus returned fields are front-loaded before the pagination note. Every clause carries information.

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?

With no output schema present, the description compensates by enumerating the returned fields (key, name, origin, question count) and the ordering/completeness guarantees. An agent has everything needed to call and interpret this tool.

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?

There is a single parameter with 100% schema description coverage, so the baseline is 3. The description clarifies that no offset/limit parameters exist and that the automation_id scopes the whole section set, but adds no format or semantics beyond what the schema provides.

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?

Names a specific verb and resource ('List the sections of an automation's Policy') and adds scope qualifiers: display order, empty sections included, and the exact fields returned. This is unmistakably distinct from siblings like listConfigFields or getAutomation.

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?

The sentence 'No offset/limit params: this is the automation's whole set of sections' tells the agent this is an unpaginated full-set read, which heads off attempts to page it. It does not name a sibling alternative or state when to prefer it over listConfigFields, so it falls short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listConnectionsList ConnectionsA
Read-onlyIdempotent
Inspect

List the authenticated user's connections (connected integration instances) for the current team. Includes team-shared instances visible to the caller, and instances another team has granted to this one, when the org-level Connections sharing setting is on. The type query parameter filters by integration type, not native OAuth provider key.

NameRequiredDescriptionDefault
typeNo
limitNo
offsetNo
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, and non-openWorld behavior, so the bar is lower. The description adds valuable context beyond annotations: it discloses that team-shared and cross-team-granted instances appear only when the org-level Connections sharing setting is on, and it clarifies the `type` filter semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler, and the core purpose is front-loaded. The first sentence is somewhat long but every clause carries useful scoping information, and the second sentence cleanly resolves a likely parameter ambiguity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with no output schema and four parameters, the description covers the key ambiguities: scope (current team), inclusion rules (team-shared, cross-team grants), and the meaning of `type`. It does not describe pagination behavior or ordering, but those are largely inferable from schema defaults and bounds.

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 only 25%, with only `team_id` documented in the schema. The description adds meaning for the ambiguous `type` parameter ('filters by integration type, not native OAuth provider key'), but it does not compensate for the undocumented `limit` and `offset` parameters beyond what their schema bounds and defaults imply.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('authenticated user's connections (connected integration instances)') scoped to 'the current team.' It clearly distinguishes connections from integrations by clarifying they are 'connected integration instances,' but it does not explicitly name or compare against sibling list tools such as listIntegrations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what is included (team-shared instances, cross-team grants) but gives no guidance on when to choose this tool over alternatives like listIntegrations or listCredentials. There are no when-to-use conditions, prerequisites, or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listCredentialsList credentials for user and teamA
Read-onlyIdempotent
Inspect

List browser-login credentials visible to the caller for the current team — team-shared (user_id IS NULL) plus the caller's own personal logins. Optionally filter by domain. Passwords and OTP secrets are never returned; only metadata flags indicating whether they are set.

NameRequiredDescriptionDefault
domainNo
userIdYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly and idempotent, so the description is free to add behavioral value. It does: passwords and OTP secrets are never returned, only metadata flags indicating whether they are set. It also clarifies the visibility boundary. It omits pagination or ordering details, but the annotation coverage lowers the bar.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core scope and behavior, with no filler. The sensitive-data caveat is stated efficiently and the optional domain filter is mentioned without extra prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the result scope, the optional filter, and the important return-value constraint (no passwords/OTP). However, a required `userId` parameter is left essentially unexplained, which is a real gap for an agent trying to invoke the tool correctly. Without an output schema, more guidance on pagination or returned metadata fields would also be helpful.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%, so the description must compensate. It adds meaning for the optional `domain` parameter, but the required `userId` parameter is neither described in the schema nor explained in the description. The relationship between `userId`, the caller, and the current team remains ambiguous, and `team_id` semantics are left entirely to the schema.

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 names the exact resource (browser-login credentials), the verb (list), and precisely scopes the result: team-shared credentials with user_id NULL plus the caller's personal logins. This clearly distinguishes it from credential or secret management siblings.

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 context of when this tool is appropriate: listing credentials visible to the caller in the current team, with an optional domain filter. It does not explicitly name alternative tools or state when not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listFilesList FilesB
Read-onlyIdempotent
Inspect

List files for the current team.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds the 'current team' scoping, but does not disclose pagination, result format, or any access-related behavior. There is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence with no filler, and the verb and object are front-loaded. It is appropriately brief for a simple list operation, though the first two words largely mirror the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is low complexity, and the annotations plus schema cover safety and team_id semantics. However, with no output schema, the description does not explain what the returned file list contains (e.g., file names, metadata, pagination), leaving some ambiguity for the agent.

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%, and the team_id parameter is thoroughly documented, including fallback behavior for API keys and OAuth. The description adds little beyond 'current team', which aligns with the schema but does not need to repeat it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb ('List') and resource ('files') with a specific scope ('current team'). It is instantly distinguishable from unrelated sibling tools, though it does not explicitly differentiate itself from similarly named tools like listSandboxFiles or listSkillFiles.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternatives such as listSandboxFiles or getFileContent. The parameter schema explains team_id semantics, but the description itself provides no usage context, prerequisites, or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listIntegrationsList IntegrationsB
Read-onlyIdempotent
Inspect

List the team's integration catalog: built-in integration types plus the custom connection types this team owns or has been granted by another team in its organization. OAuth authorization flows are browser-based and cannot be performed via this API; use the Duvo dashboard to complete OAuth-based connections.

NameRequiredDescriptionDefault
typeNo
limitNo
offsetNo
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, covering safety. The description adds valuable context: OAuth authorization flows are browser-based and cannot be performed via this API, directing users to the dashboard. It also clarifies the scope of listed items (owned/granted custom connections). This goes beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise, two sentences, with the main purpose front-loaded in the first sentence and the OAuth caveat in the second. No fluff or redundancy; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 4 parameters and no output schema, the description omits critical details: it doesn't explain the 'type' parameter, pagination (limit/offset), or what the response contains. While the OAuth limitation is noted, the overall description is insufficient for an agent to confidently call this tool with correct parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 25% (only team_id has a description). The description does not mention any of the four parameters, nor does it explain what 'type' means or how limit/offset work. It fails to compensate for the low schema coverage, leaving agents without essential parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List' and the resource 'integration catalog', specifying it includes built-in integration types and custom connection types owned or granted. This is specific and unambiguous, but it does not explicitly differentiate from sibling tools like listConnections or listRevisionIntegrations, which could overlap in scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives such as listConnections or listPluginCatalog. The only usage note is about OAuth flows requiring the dashboard, which is behavioral rather than selection-oriented. No exclusions or alternative routing are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listMyOrganizationsList My OrganizationsA
Read-onlyIdempotent
Inspect

List the organizations the current user belongs to, with their role (organization:member, organization:admin, organization:owner, or organization:executive) and member count in each. Use this to check whether the user has an admin-or-above role before calling organization-scoped endpoints, which reject lower roles with 403.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already indicate readOnly and idempotent behavior. The description adds that it returns roles and member counts, and scopes to the current user. It does not contradict annotations and provides useful output detail, though it could mention potential errors or edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured, consisting of a clear listing statement and a usage note. No unnecessary verbosity or redundancy.

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?

Given there is no output schema, the description explains the return content (role and member count) and the practical context. It is complete for the tool's intended use, including the error condition it helps avoid.

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?

There are no parameters, so the schema is fully covered (100%). The description does not need to explain parameter semantics, and the baseline for high coverage is 3.

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 clearly states the tool lists the organizations the current user belongs to, including role and member count. It also specifies a concrete use case (checking admin-or-above role) which distinguishes it from related tools like listMyTeams.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use this tool: to check if the user has an admin-or-above role before calling organization-scoped endpoints that reject lower roles with 403. This provides clear guidance on the appropriate context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listMyTeamsList My TeamsA
Read-onlyIdempotent
Inspect

List teams the authenticated caller can act on. Team-scoped API keys see only the key's team; managed Ask Duvo keys stay within their origin boundary; human user-scoped API keys and OAuth callers see every team they're a member of.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is read-only, idempotent, and non-destructive. The description adds valuable behavioral detail beyond annotations by explaining auth-dependent visibility boundaries, which is important for setting caller expectations about the result set.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, tightly written sentence that leads with the core purpose and then provides the essential scoping nuance. Every clause adds meaningful information without unnecessary filler.

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 parameterless, read-only list tool with strong annotations, the description is complete. It covers what the tool returns, which teams are visible under each auth context, and the operation's safety profile is already established by annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is no parameter semantics burden on the description. The baseline of 4 applies because the description is not required to compensate for undocumented parameters.

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 clearly states the operation ('List teams') and the specific resource scope ('teams the authenticated caller can act on'). It further differentiates behavior across credential types, which distinguishes it from sibling list tools like listOrgTeams and listMyOrganizations.

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?

The description provides clear context about which teams will be returned for different authentication modes, making it evident this is the correct tool for listing personally accessible teams. It does not explicitly name alternatives or exclusion conditions, but the scoping rules effectively imply when to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listNotificationsList NotificationsA
Read-onlyIdempotent
Inspect

List notifications for the authenticated user's current team, most recent first. Filter with type, unread, severity or minSeverity (mutually exclusive), important, agentRunId, or processId; paginate with limit/cursor. Pass batchId to list only the live members of a notification batch, optionally ordered by sort=importance (only valid together with batchId). Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
sortNoimportance orders by type importance then severity (only valid together with batchId); default recency.recency
typeNoOnly return notifications of this type. One of: connection_broken, login_broken, case_failed, critical_case_issue, case_issue, critical_eval_issue, eval_issue, job_issue, job_done, background_job, schedule_issue, config_proposal, routine_candidate.
limitNoNumber of notifications per page (1-100, default 30).
cursorNoOpaque cursor from the previous page's nextCursor. Omit for the first page.
unreadNoIf true, only return unread notifications.
batchIdNoOnly return live members of this notification batch.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
severityNoOnly return notifications with this severity. One of: info, warning, critical, success.
importantNoIf true, only return important notifications: unresolved connection_broken rows pinned until reconnected, removed, or dismissed.
processIdNoOnly return notifications about this Clarity process.
agentRunIdNoOnly return notifications about this agent run.
minSeverityNoOnly return notifications at or above this urgency. Least to most urgent: success < info < warning < critical. Mutually exclusive with severity.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is fully covered elsewhere. The description adds genuinely new behavior: ordering (most recent first), the 404 when Notification Center is disabled, and that batchId returns only 'live' members. That is useful, but it says nothing about the response envelope or how cursor/nextCursor round-trips beyond 'paginate with limit/cursor'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and ordering, then filters, then pagination, then the prerequisite/404 caveat — a sensible order. The middle clause enumerating every filter is a run-on that mostly duplicates schema and could be trimmed without loss, keeping it short of a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 12 optional parameters and no output schema, the description covers invocation adequately: no required params, how to page, mutual exclusions, and the feature-gate failure mode. The remaining omission is what a returned notification contains and how batch member ordering interacts with pagination, which matters given no output schema exists to cover it.

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%, including enum value lists and the severity/minSeverity mutual exclusivity and sort-with-batchId constraint, so the description is largely restating structured data. It does reinforce the constraint pairings in one place, which is convenient, but adds no format, default, or boundary detail the schema lacks. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource and scope: 'List notifications for the authenticated user's current team, most recent first.' That is unambiguous about what it returns and the default ordering. It does not, however, name or distinguish itself from nearby siblings such as getNotificationFeed, getNotificationBatch, or getUnreadNotificationCount, leaving the agent to infer which list-shaped tool to pick.

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?

Gives concrete usage guidance inside the call: which filters exist, that severity and minSeverity are mutually exclusive, that sort=importance is only valid together with batchId, and how to paginate. It also states the prerequisite (Notification Center feature, 404 otherwise). The gap is that it never says when to prefer this over sibling notification tools such as getNotificationCounts or dismissNotification.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listOrgAgentsList Org AgentsA
Read-onlyIdempotent
Inspect

List every agent across all teams in an organization, with the team it belongs to, the state of its most recent run and the state of its schedules. Intended for external monitoring: it answers 'which agents have gone silent' and 'which agents were switched off' without a request per team or per agent. Requires an organization Admin, Executive, or Owner role, and an API key scoped to all teams you can access — a key pinned to a single team is rejected, because this endpoint spans every team in the organization.

NameRequiredDescriptionDefault
limitNoNumber of agents per page (1-100, default 20)
orgIdYesThe organization's unique identifier
offsetNoNumber of agents to skip
team_idNoFilter to agents on this team
auto_disabledNoIf true, only agents whose schedule was switched off automatically (e.g. after repeated missing-connection failures); if false, only agents with no auto-disabled schedule
schedule_enabledNoIf true, only agents with at least one enabled schedule; if false, only agents with none (including agents that are never scheduled)

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool as read-only, idempotent, and non-destructive. The description adds substantial behavior beyond annotations: organization-wide scope, required Admin/Executive/Owner role, and rejection of single-team API keys with a clear rationale. This is exactly the kind of contextual disclosure that helps an agent avoid auth failures.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loaded with purpose, then use case, then auth. Each sentence earns its place and there is no filler or redundant detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter listing tool with no output schema, the description covers purpose, use case, returned fields, and auth prerequisites, while the schema covers all parameters. The only notable gap is that it does not explicitly mention pagination or the response envelope, which would be useful given the limit/offset parameters and absence of an output schema.

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 all six parameters are already fully documented with types, defaults, ranges, and enums. The description adds no parameter-level detail beyond what the schema provides, so the baseline 3 applies.

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 action and resource: 'List every agent across all teams in an organization,' and enumerates the returned fields (team, most recent run state, schedule states). This scope clearly differentiates it from sibling per-team/per-agent list tools such as listAgents and listQueueAgents.

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 explicitly states the intended use case ('external monitoring'), the questions it answers, and the required role and API-key scope. It does not name sibling alternatives or give explicit when-not-to-use conditions, but the 'without a request per team or per agent' contrast provides strong routing context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listOrgRunsList Org RunsA
Read-onlyIdempotent
Inspect

List runs across every team in an organization, filtered by status, agent, team, source, evaluation issues and time. Intended for external monitoring: one call covers the whole org instead of one per team. Requires an organization Admin, Executive, or Owner role, and an API key scoped to all teams you can access — a key pinned to a single team is rejected, because this endpoint spans every team in the organization.

NameRequiredDescriptionDefault
limitNoNumber of runs per page (1-500, default 20). The cap is higher than the team runs endpoint's because this route serves bulk export: at 100 requests a minute per key, page size is what bounds how fast a month of runs can be pulled.
orgIdYesThe organization's unique identifier
sinceNoAlias of `completed_after`, kept because it is the name the public team runs endpoint ships. Prefer `completed_after`: this endpoint carries a creation and a start window too, and only the column-named pair says which one this is.
untilNoAlias of `completed_before`, kept because it is the name the public team runs endpoint ships. Prefer `completed_before`.
cursorNoResume after the run a previous page ended on: pass the `next_cursor` that page returned, with the same filters and sort_order. Runs created or resolved in between cannot shift a boundary you have already passed, so a sweep sees every run exactly once, and a sweep that started under the default 7-day window keeps that window on every page. This list has no offset parameter: skipping rows costs the database every skipped row, and a run created between two requests shifts every later offset by one, so an offset sweep can repeat or miss a run. 400 when the value is not a cursor this endpoint issued.
sourceNoFilter to runs created from this source (e.g. api, scheduling)
statusNoFilter to runs with this status. `needs_attention` is the monitoring status: runs that are waiting on a human or failed, plus runs whose latest evaluation flagged a critical issue — a run can finish as `completed` and still have accomplished nothing.
team_idNoFilter to runs on this team
agent_idNoFilter to runs for this agent
count_onlyNoSkip row selection and enrichment. The normal list response shape is returned with an empty row array and the matching total.false
has_issuesNoFilter on the run's latest successful evaluation: true returns only runs it flagged, false only runs it did not. Only the latest evaluation counts — an older flag does not match — and a run whose latest evaluation errored, or that has none, counts as unflagged. Omit to return both.
sort_orderNoSort direction on created_at (default desc)desc
created_afterNoReturn runs created at or after this ISO-8601 timestamp. Every run has a creation time, so this is the window that returns all runs in a period whatever state they reached — unlike the started and completed windows below, which exclude runs that never started and runs still in flight respectively. When the request carries no lower time bound (`created_after`, `started_after`, `completed_after` or `since`), this defaults to 7 days ago and `default_window_applied` is true in the response: an organization's run history is unbounded, and a monitor wants what is recent. An upper bound alone keeps the default floor. Pass any lower bound to replace it.
include_totalNoReturn `total`, the count of every matching run ignoring pagination. Off by default: counting walks every match where the page stops at `limit`, so on a large organization it costs orders of magnitude more than the rows themselves. Ask for it when you are driving a pager, not when you are polling. Implied by `count_only`.false
started_afterNoReturn runs that started at or after this ISO-8601 timestamp. Runs that never started are excluded. Pair with `started_before` to bound a stuck-run query to a window — without a lower bound, `status=running` also counts every run left running months ago.
created_beforeNoReturn runs created before this ISO-8601 timestamp (exclusive). Pair with `created_after` for a period. A closed creation window is also the stable one to paginate: results are ordered by creation time, so runs arriving mid-sweep cannot shift a closed window's pages.
issue_severityNoOnly runs whose latest successful evaluation has at least one failing rubric at this severity (critical | medium | low). Implies has_issues.
started_beforeNoReturn runs that started before this ISO-8601 timestamp. Combine with status=running to find stuck runs — `since`/`until` filter on completion, so they never match a run that is still going.
completed_afterNoReturn runs completed at or after this ISO-8601 timestamp. Runs that have not completed are excluded, including every stuck one — reach for `started_after`/`started_before` to bound those. Alias of `since`; pass one or the other, not both.
completed_beforeNoReturn runs completed before this ISO-8601 timestamp (exclusive). Runs that have not completed are excluded. Alias of `until`; pass one or the other, not both.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/closed-world, so the safety profile is covered. The description adds genuinely extra operational context: the required admin/executive/owner role and the constraint that an API key pinned to a single team is rejected. It does not restate annotation content, adding real value beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tightly packed sentences: purpose/scope, the monitoring rationale, then the hard auth prerequisite. The gating information is front-loaded and nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 20-parameter read tool with no output schema and full annotation coverage, the description supplies the selection-critical facts: org-wide scope, the monitoring use case, and the role/key prerequisites. Pagination, the default 7-day window and return shape are left to the schema, which is acceptable, though a mention of the pagination model would round it out.

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% and the per-parameter descriptions are unusually thorough (aliasing, defaults, pagination semantics, rate-limit rationale). The description itself adds no parameter-level meaning, so it sits at the baseline of 3 with the schema doing all the heavy lifting.

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?

States a specific verb and resource ('List runs') plus a precise scope ('across every team in an organization'), immediately distinguishing it from the team-scoped runs siblings. An agent can tell this apart from listRuns/listTeamRuns without opening any schema.

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?

'Intended for external monitoring: one call covers the whole org instead of one per team' gives a clear when-to-use and implies the alternative of calling per team. It stops short of naming the concrete sibling tool (e.g. listRuns) that the per-team path would use, so the routing is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listOrgTeamsList Org TeamsA
Read-onlyIdempotent
Inspect

List teams belonging to an organization you are a member of, including your membership and role in each.

NameRequiredDescriptionDefault
limitNoNumber of teams per page (1-100, default 50)
orgIdYesOrganization ID
offsetNoNumber of teams to skip
searchNoFilter teams by name (case-insensitive substring match)
sortByNoSort order: createdAt (newest first, default) or name (alphabetical)createdAt

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful behavioral context: it returns the caller's membership and role per team and restricts listing to organizations the caller belongs to. It does not go into pagination or response structure, but that is a minor gap given the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. Every clause contributes meaning: listing teams, org membership scope, and the inclusion of membership/role in the response.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a low-complexity, read-only list operation with a fully documented schema and safety annotations, the description is nearly complete. The only minor gap is that it does not explicitly state whether teams in the org where the caller lacks a team membership are still returned or how the role field behaves in that case.

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 all five parameters are already documented in the input schema. The description does not need to restate them and adds little beyond hinting at the orgId scope; the baseline of 3 is appropriate.

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 states a specific verb (List), a resource (teams), an owning scope (an organization you are a member of), and the additional data returned (your membership and role in each). This makes it clearly distinguishable from related siblings like getTeam, listTeamMembers, and listMyTeams.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies its use case by defining the org membership scope and the membership/role information returned. However, it does not explicitly contrast it with close siblings such as listMyTeams or getTeam, nor does it state when not to use this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listPluginCatalogList Plugin CatalogA
Read-onlyIdempotent
Inspect

List plugins that can be referenced by name in a build's plugins array. Builds may also reference any public GitHub repository URL (https://github.com/owner/repo) as a plugin; those are not enumerated here.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: the catalog is scoped to name-referenced plugins only, and URL-referenced plugins are intentionally absent. This sets accurate expectations about the result set.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly written sentences deliver the core purpose and the key exclusion without any filler. The main scoping statement comes first, and the GitHub URL exclusion is a necessary second sentence. Every word earns its place.

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 parameterless list tool with rich annotations, the description is complete: it states what the catalog contains, how plugins are referenced, and what is not included. There is no output schema, but the return concept—a list of pluginnames—is simple enough that no further detail is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and schema coverage is 100%, so there are no parameter semantics to explain. The description correctly focuses on result scope rather than arguments. This is the appropriate baseline for a parameterless tool.

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 states a specific action and resource: listing plugins that can be referenced by name in a build's plugins array. It also differentiates itself from the broader category by explicitly noting that public GitHub repository URL plugins are not enumerated, making its scope clear relative to potential alternatives.

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?

The description gives clear context: use this tool when you need plugins that can be referenced by name in a build. It also provides an explicit exclusion—GitHub repository URL plugins are not included—which helps an agent avoid misusing it. It does not name a specific sibling tool as an alternative, but the usage boundary is clear enough.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listProcessRolesList Process RolesA
Read-onlyIdempotent
Inspect

List the process roles of an automation (Operator, Executive, Approver and the like, defined on that one automation, not the team's Admin/Member/Builder roles) with what each can do and who holds it. Answer "who can see X", "who has which role" and "what does each role see" on an automation from this, not from team membership or dashboard sharing. Each role has its key (pass it to assignProcessMember), label, can_act_on_cases, can_view_manage, the dashboards it opens, its members and its pending_invites. dashboards_shared_individually are pinned dashboards a role alone does not open: say they must be shared with the person too. dashboards_creator_only read a live Connection and open only for their creator. When roster.complete is false the lists were cut off: say so, give the totals, and point to the People tab (urls.people) instead of saying who holds a role. Give the user the full urls, not the paths. Managers and above only.

NameRequiredDescriptionDefault
automation_idYesAutomation ID

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive, closed-world behavior. The description adds substantial context beyond that: the Managers-and-above authorization requirement, how to interpret `dashboards_shared_individually` and `dashboards_creator_only`, and what to do when `roster.complete` is false due to truncation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The paragraph is front-loaded with the tool's purpose, then moves through usage, returned fields, caveats, and authorization. Every sentence carries actionable information, and the length is justified by the rich return structure and the absence of an output schema.

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?

With no output schema, the description compensates by explaining the returned role fields, dashboard-sharing nuances, truncation handling, and URL formatting. Combined with annotations covering safety, it gives an agent enough to invoke and interpret the tool correctly.

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 coverage is 100% for the single required `automation_id` parameter, and the schema already documents its UUID format. The description does not add parameter-specific syntax or edge-case guidance beyond implying the automation scope, so the baseline of 3 is appropriate.

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 gives a specific verb and resource ("List the process roles of an automation") and immediately scopes it with examples and exclusions. It distinguishes these automation-defined roles from team-level Admin/Member/Builder roles, which helps an agent select this tool over team-membership or sharing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says which questions this tool answers ("who can see X", "who has which role", "what does each role see") and which sources not to use (team membership or dashboard sharing). It also names assignProcessMember as the downstream tool for the returned role `key`, giving clear routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listPulseDashboardCommentsList Pulse Dashboard CommentsA
Read-onlyIdempotent
Inspect

List the comment threads on a Duvo Pulse dashboard (requires view access). Each thread carries its author, the dashboard element it is pinned to, its replies oldest-first, and whether it has been marked complete.

NameRequiredDescriptionDefault
limitNoMaximum number of comment threads to return (1-200, default 50).
offsetNoNumber of comment threads to skip, for paging.
statusNoReturn only threads in this state: `open` for threads not yet marked complete, `complete` for those that are. Omit for both. `total` and `open_total` always count the whole set, so a filtered page still reports how many threads exist.
artifactIdYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint and idempotentHint annotations, the description adds useful behavioral details: it requires view access, and the status parameter description notes that total and open_total counts reflect the whole set regardless of filtering. These details help the agent understand side effects and response behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is succinct and well-structured, consisting of two clear sentences. It avoids unnecessary detail while conveying the essential purpose and a brief overview of the returned data, making it easy for the agent to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema, the description partially compensates by mentioning what each thread carries (author, pinned element, replies order, completion status). It also covers permission requirements and pagination parameters. This is adequate for a list operation, though a more explicit return type would improve completeness.

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?

The schema already provides descriptions for limit, offset, and status (75% coverage). The tool description adds little to parameter understanding—only that the dashboard is identified by artifactId, which is implicit. Since coverage is moderate and the description doesn't enrich the parameter meanings significantly, a score of 3 is appropriate.

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 clearly states the tool lists comment threads on a Duvo Pulse dashboard, specifying the resource (dashboard) and action (list comment threads). It also mentions the required view access, making the purpose unambiguous and distinct from sibling tools like listPulseDashboards or listPulseDashboardMessages.

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?

The description implicitly indicates when to use this tool (when comment threads are needed) but does not explicitly contrast it with alternatives such as listPulseDashboardMessages. The context of sibling tools provides enough differentiation, but explicit guidance would be stronger.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listPulseDashboardConnectionsList Pulse Dashboard ConnectionsA
Read-onlyIdempotent
Inspect

List the connections (data sources) attached to a Duvo Pulse dashboard (requires edit access).

NameRequiredDescriptionDefault
artifactIdYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a read-only, idempotent, non-destructive operation. The description adds an important behavioral detail beyond the annotations: it requires edit access to the dashboard. It does not describe return format or pagination, but for a simple read-only list operation the annotations carry the safety profile and the access requirement adds meaningful context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence. Every element earns its place: the resource, the scope ('attached to a dashboard'), the clarification that connections are data sources, and the edit-access requirement. No filler or redundant phrasing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter, read-only tool with clarifying annotations, the description is largely complete: it states the purpose, scope, and access requirement. The lack of an output schema means the return value is not formally documented, but the likely result—a list of connections/data sources—is strongly implied by the tool name and description.

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?

The schema has 0% description coverage, so the description must compensate. The phrase 'attached to a Duvo Pulse dashboard' implicitly identifies artifactId as the dashboard ID, and the parameter name plus format constraint help further. However, the description never explicitly maps artifactId to the dashboard, so the semantic link is inferred rather than stated.

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 uses a specific verb ('List') and resource ('connections (data sources) attached to a Duvo Pulse dashboard'), clearly clarifying that 'connections' means data sources. This also distinguishes it from broader tools like listConnections and from other dashboard-specific listers such as listPulseDashboards or listPulseDashboardVersions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives useful context by noting that listing requires edit access, which sets an implicit prerequisite. However, it does not explicitly state when to prefer this tool over alternatives such as the generic listConnections or the related getPulseDashboard, leaving the usage guidance mostly implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listPulseDashboardMessagesList Pulse Dashboard MessagesA
Read-onlyIdempotent
Inspect

List the chat transcript of a Duvo Pulse dashboard's live version (requires edit access). Returns the most recent page by default, oldest first within the page; pass before (a message id from a previous page) to walk back through older messages. Messages from other version branches are not included.

NameRequiredDescriptionDefault
limitNoMaximum number of messages to return (1-500, default 50).
beforeNoMessage id cursor: return the page of messages immediately older than this message. Omit for the most recent page.
artifactIdYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so safety is covered. The description adds substantial behavioral context beyond that: pagination direction ('oldest first within the page'), default page behavior, cursor semantics for 'before', the edit-access prerequisite, and exclusion of other version branches. This is rich, useful behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences with no filler. Key facts are front-loaded: purpose, permission requirement, then pagination and scope exclusions. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read tool with annotations covering safety, the description covers purpose, access, ordering, pagination, and branch filtering. There is no output schema, so a bit more about return shape would help, and the artifactId parameter is never explained. These are minor gaps given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds little beyond the schema: it restates the 'before' cursor concept and mentions the live version, but it does not explain the required artifactId parameter, which has no schema description. With schema coverage at 67% and the missing param being the only required one, the description should have compensated but did not.

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 uses a specific verb and resource: 'List the chat transcript of a Duvo Pulse dashboard's live version'. It also clarifies scope by stating that messages from other version branches are not included, which distinguishes it from related version and dashboard tools. The tool is clearly differentiated from siblings like sendPulseDashboardMessage and getPulseDashboard.

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?

The description provides clear context for when to use the tool: to read the live version's chat transcript, and it notes the edit-access requirement. It also explains pagination behavior, which is a usage condition. However, it does not explicitly name alternative tools or state when to use them instead, so it stops short of full exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listPulseDashboardsList Pulse DashboardsA
Read-onlyIdempotent
Inspect

List your Duvo Pulse dashboards (live, agent-generated visualizations of your Duvo data). Ordered most recently updated first, except scope=automation, which is ordered by creation time (then id) so the whole scope can be read with the after_id cursor without a concurrent change shifting a page boundary.

NameRequiredDescriptionDefault
limitNoNumber of results per page (1-100, default 20)
scopeNoWhich dashboards to return: 'created' (yours, the default), 'team' (published to your whole team by a teammate), 'shared' (shared with you individually by a teammate), or 'automation' (owned by one of your team's automations, each carrying its automation's name).created
offsetNoNumber of results to skip
after_idNoKeyset cursor for reading the whole 'automation' scope: the id of the last dashboard you received; returns the page after it in (created_at, id) order. Use this instead of 'offset' when reading every page, so a dashboard created, updated or deleted between requests cannot shift a page boundary you have already passed. 400 when the id no longer names a dashboard (restart from the first page). Only valid with scope=automation.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal read-only, idempotent, and non-destructive behavior. The description adds valuable behavioral detail beyond annotations: the ordering rule (most recently updated first, except automation which uses creation time then id) and the rationale for using after_id to avoid page-boundary shifts under concurrency. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler. The purpose is front-loaded, and the second sentence packs the complex ordering/cursor behavior into a compact, technically precise explanation. Every part earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has no output schema, and the description does not describe the response shape or pagination metadata, which is a minor gap for a list operation. However, given the fully documented parameters, read-only annotations, and the description's coverage of ordering and cursor behavior, the agent has enough to invoke it correctly.

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 coverage is 100% with rich descriptions for all four parameters. The tool description mostly reinforces the after_id ordering rationale already detailed in the schema, so it adds little semantic value beyond what the input schema already provides.

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 uses a specific verb ('List') and resource ('Duvo Pulse dashboards'), and the parenthetical defines exactly what those are. It is clearly distinct from sibling tools like listPulseDashboardConnections, listPulseDashboardMessages, listPulseDashboardVersions, and getPulseDashboard.

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?

The description gives clear context for when to use this tool — when you want to list Pulse dashboards — and explains the special ordering/cursor behavior for scope=automation. However, it does not explicitly name alternatives or state when not to use this tool, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listPulseDashboardVersionsList Pulse Dashboard VersionsA
Read-onlyIdempotent
Inspect

List the version history of a Duvo Pulse dashboard, newest first (requires edit access). Use the version id with the restore and version-render endpoints.

NameRequiredDescriptionDefault
artifactIdYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so safety is covered. The description adds helpful behavioral context beyond annotations: the edit-access requirement, newest-first ordering, and downstream consumption of the version id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The core action and ordering are front-loaded, and the second sentence provides practical downstream guidance without redundancy.

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 simple one-parameter, read-only list operation with strong annotations, the description covers the resource, access requirements, ordering, and how the result should be used. Nothing essential is missing.

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 0%, so the description carries some burden, but with only a single required artifactId, the phrase 'of a Duvo Pulse dashboard' clarifies the parameter's role. It doesn't explicitly name or explain the parameter format, making this adequate but not exceptional.

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?

States a specific verb and resource: 'List the version history of a Duvo Pulse dashboard' with ordering 'newest first.' It also distinguishes itself from related Pulse tools by noting the version id is meant for the restore and version-render endpoints.

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?

Gives clear usage context by noting that edit access is required and that the returned version id should be used with the restore and version-render endpoints. It doesn't explicitly enumerate when not to use this tool versus siblings, but the guidance is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listQueueAgentsList Queue AgentsA
Read-onlyIdempotent
Inspect

List agents bound to a queue as producers (agents that push cases into the queue) or consumers (agents triggered by cases in the queue).

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds useful domain context about producer/consumer semantics, but does not disclose behavioral details such as pagination, ordering, or permission requirements. This is acceptable given the annotations, but not exceptional.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, well-structured sentence front-loads the core action and resource, then uses parenthetical clarification for the two roles. No filler or redundance; every part earns its place.

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 simple read-only list operation with one required, well-documented parameter and annotations covering idempotency and non-destructiveness, the description is complete. An agent has enough information to invoke it correctly without needing an output schema or additional behavioral notes.

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?

The schema fully documents queue_id with format, pattern, and a clear description ('The queue's unique identifier'), so schema coverage is 100%. The description reinforces that the queue is the binding context but does not add parameter-level meaning beyond the schema, matching the baseline for full coverage.

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?

States a specific verb and resource: 'List agents bound to a queue'. It also clarifies two distinct roles — producers (push cases into the queue) and consumers (triggered by cases in the queue) — which distinguishes this from generic agent-listing tools like listAgents or listQueues.

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?

The description makes clear it is about queue-agent bindings rather than all agents or all queues, giving an agent enough context to select it over generic sibling tools. It does not explicitly name alternatives or state when not to use it, so it stops short of full exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listQueueAggregationsList Queue AggregationsB
Read-onlyIdempotent
Inspect

List a queue's aggregation definitions.

NameRequiredDescriptionDefault
limitNo
offsetNo
queue_idYesThe queue's unique identifier

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, and non-destructive behavior, and the description adds that the result is the queue's 'aggregation definitions' rather than computed results. It does not disclose pagination behavior, ordering, or the response when a queue has no aggregations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler or repetition. Every word contributes to identifying the verb and resource.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple and annotations cover its safety profile, so the core one-liner is close to adequate. However, with no output schema, it would be stronger with a note about pagination and a distinction from result/evaluate/refresh aggregation siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33%; queue_id is documented, but limit and offset are not described in the schema or the tool description. The description adds no meaning for the pagination parameters, which is a notable gap at this coverage level.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('List') and a scoped resource ('a queue's aggregation definitions'), making the operation identifiable. It is distinguishable from siblings like getQueueAggregationResult or refreshQueueAggregation by the word 'definitions', though it does not explicitly name those alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided for when to use this tool versus alternatives such as getQueueAggregationResult, evaluateQueueAggregation, or createQueueAggregation. The only usage signal is the verb 'List', leaving the agent to infer context from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listQueueLabelsList Queue LabelsA
Read-onlyIdempotent
Inspect

List every label defined on a queue along with the count of cases each label is assigned to.

NameRequiredDescriptionDefault
limitNoNumber of labels per page (1-1000, default 1000).
offsetNoZero-based offset for pagination.
queue_idYesThe queue's unique identifier

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is clear. The description adds the result shape (label and case count) but does not disclose pagination behavior, ordering, or whether counts include only active cases. No contradiction with annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, focused sentence that states scope, resource, and returned information without any filler. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with one required parameter and three documented parameters, the description is adequately complete. It explains the list scope and the per-item count. It could mention pagination explicitly, but the limit/offset parameters already signal this.

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 every parameter is already documented in the input schema with type and meaning. The description does not add parameter-level detail, but the schema carries the burden, so a baseline 3 is appropriate.

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 states a specific action ('List'), a clear resource ('every label defined on a queue'), and a distinctive result ('count of cases each label is assigned to'). This clearly distinguishes it from sibling tools like listCaseLabels or listClarityProcessLabels by scoping labels to a queue with case counts.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not provide any explicit guidance on when to use this tool versus alternatives such as listCaseLabels. It implies queue-level label enumeration through the queue_id parameter, but there is no stated exclusion, prerequisite, or comparison to sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listQueuesList QueuesB
Read-onlyIdempotent
Inspect

List queues for your team.

NameRequiredDescriptionDefault
limitNoNumber of queues per page (1-250, default 250)
offsetNoNumber of queues to skip
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
automation_idNoOnly return queues belonging to this automation.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as read-only, idempotent, and non-destructive, so the safety profile is covered. The description adds the team-scoping context, but it does not disclose pagination behavior, response shape, or any additional behavioral traits beyond what annotations already provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence conveys the tool's purpose without unnecessary words. For such a simple listing operation, this is appropriately concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the low complexity, rich parameter descriptions, and annotations covering safety, the description is largely sufficient. It could be slightly stronger by mentioning pagination or return shape, but nothing critical is missing for an agent to call it correctly.

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%, with each parameter (limit, offset, team_id, automation_id) clearly documented. The description itself adds no parameter-level meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('List') and resource ('queues'), with a team scope. It does not explicitly differentiate itself from sibling tools like getQueue, listQueueAgents, or listQueueLabels, but the primary purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternatives. It does not mention that this is for paginated/bulk queue listing, nor does it distinguish from getQueue or other queue-related list tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listRevisionIntegrationConnectionsList Revision Integration ConnectionsA
Read-onlyIdempotent
Inspect

List the connections you have pinned to this build's integration slot. Multi-pin is supported: you can pin multiple connections to the same slot.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID
integration_idYesIntegration ID (catalog integration ID or slot ID from the list response)

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly, idempotent, and non-destructive behavior. The description adds a useful behavioral detail beyond annotations: multi-pin is supported, so multiple connections may appear for the same slot. It does not cover return format or pagination, but for a simple read-only list this is a reasonable level of disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler; the primary action and target are front-loaded. The second sentence adds only the non-obvious multi-pin behavior. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation, the description, schema, and annotations give an agent enough to call it correctly. It does not describe the return shape, but no output schema exists and the purpose makes the response type predictable. Slight ambiguity around what exactly an 'integration slot' is remains, but the schema's integration_id note mitigates it.

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?

The input schema already documents all three parameters with descriptions, including the note that integration_id can be a slot ID. The description itself adds no parameter-level meaning. With full schema coverage, a baseline of 3 is appropriate.

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?

States a clear verb and resource: it lists connections pinned to a build's integration slot, not all connections. The 'pinned' and 'slot' wording distinguishes it from broader tools like listConnections and listRevisionIntegrations. The multi-pin note further clarifies the scope of what is being listed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the use case – inspecting pinned connections for a build's integration slot – but does not explicitly say when to prefer it over alternatives like listRevisionIntegrations or listConnections. It provides no exclusions or prerequisites. The context is inferable, but explicit routing guidance is missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listRevisionIntegrationQueuesList Revision Integration QueuesA
Read-onlyIdempotent
Inspect

List the queues linked to this build's case-queue integration slot. Only meaningful for case-queue-producer and case-queue-consumer integrations.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID
integration_idYesIntegration ID

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety and mutation profile is covered. The description adds an applicability qualifier but does not disclose return shape, pagination, or what 'linked queues' means. No contradiction with annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences: the first states the action and resource, the second adds a necessary scope qualifier. There is no filler, repetition of schema details, or unnecessary domain explanation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with fully schema-covered UUID parameters and safety annotations, the description supplies the essential selection context. The only minor gap is that it assumes familiarity with the 'case-queue integration slot' concept and does not describe the response shape, but no output schema exists and the operation is straightforward.

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?

All three parameters are fully described in the schema with UUID formats and 'Agent ID', 'Build ID', and 'Integration ID' labels. The description adds domain context about case-queue integrations but does not meaningfully elaborate on the individual parameters beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('List') and identifies a precise resource: queues linked to a build's case-queue integration slot. It also narrows applicability to case-queue-producer and case-queue-consumer integrations. It does not explicitly contrast itself with siblings like listRevisionIntegrationConnections or listRevisionIntegrations, so it falls just short of a 5.

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?

The phrase 'Only meaningful for case-queue-producer and case-queue-consumer integrations' provides clear context for when the tool applies and implicitly warns against using it for other integration types. It does not name specific alternative tools or give an explicit 'when not to use' beyond that applicability condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listRevisionIntegrationsList Revision IntegrationsB
Read-onlyIdempotent
Inspect

List integrations attached to an agent revision.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds only the scope 'attached to an agent revision,' which is useful but not rich behavioral context such as ordering, pagination, or return shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that is front-loaded and free of fluff. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list operation with two clearly-specified UUID parameters, the description is largely complete. However, with no output schema and no mention of what fields or entities the returned integrations contain, there is a minor gap, and sibling confusion is not addressed.

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 both agent_id and build_id are documented in the schema with format and pattern constraints. The description adds no additional parameter meaning beyond what the schema already provides, which matches the baseline for full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: list integrations attached to an agent revision. It is clear and distinct from the generic listIntegrations sibling, but it does not explicitly differentiate itself from closely related siblings like listRevisionIntegrationConnections or listRevisionIntegrationQueues.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus alternative integration-related list tools. An agent might confuse it with listIntegrations, listRevisionIntegrationConnections, or listRevisionIntegrationQueues without additional context about what distinguishes 'integrations' from these related resources.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listRevisionLoginsList Revision LoginsA
Read-onlyIdempotent
Inspect

List logins attached to a specific revision (build) of an assignment. Returns metadata only — passwords and OTP secrets are never exposed.

NameRequiredDescriptionDefault
agentIdYes
buildIdYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as read-only, idempotent, and non-destructive. The description adds valuable context beyond annotations by stating the return is metadata only and that passwords and OTP secrets are never exposed, which is critical for an agent handling sensitive login data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler. The core operation, scope, and important security constraint are front-loaded and concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with strong annotations, the description covers the essential operation and safety expectations. It lacks detail on the exact fields returned or pagination, but this is minor given the tool's simplicity and the secrecy guarantee.

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 coverage is 0%, so the description carries the burden of explaining parameters. It clarifies that 'build' means a revision and ties the tool to an assignment, which helps infer that agentId identifies the assignment and buildId identifies the revision. However, it never explicitly names or maps the parameters.

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 clearly states the verb (List), resource (logins attached to a specific revision/build of an assignment), and scope. It is easy to distinguish from sibling tools like attachRevisionLogin, detachRevisionLogin, and listRevisionSecrets.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage by defining what the tool lists, but it does not explicitly state when to use this tool versus alternatives like listRevisionSecrets or listRevisionIntegrations. No exclusions or routing guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listRevisionSecretsList Revision SecretsA
Read-onlyIdempotent
Inspect

List env-var secrets attached to a specific revision (build) of an assignment. Returns metadata and env-var keys only — secret values are never exposed.

NameRequiredDescriptionDefault
agentIdYes
buildIdYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds meaningful behavioral context by stating that secret values are never exposed and that only metadata and env-var keys are returned — privacy-relevant behavior not inferable from the annotations or schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The action and target are front-loaded, and the return-behavior caveat about secret values is included in a compact, high-value clause.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list-only tool with two required parameters and no output schema, the description gives a clear scope and a basic return contract: metadata and env-var keys. It could be more complete by listing what metadata is included, but it is sufficient for correct invocation.

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 0%, so the description must compensate. It maps buildId to 'revision (build)' and agentId to 'assignment', which gives useful semantic context. However, it does not explicitly name which parameter is which, or explain how to obtain these IDs, leaving some semantic work undone.

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?

States a specific verb ('List') and resource ('env-var secrets attached to a specific revision (build) of an assignment'). It clearly differentiates from siblings like attachRevisionSecret, detachRevisionSecret, and listSecrets by targeting revision-scoped secrets, and adds that only metadata and keys are returned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool: when you need the env-var secret keys and metadata for a particular revision/build. However, it does not explicitly mention alternatives, such as listSecrets for org-level secrets or getSecret for retrieving a secret value, so the agent is left to infer the intended context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listRunMessagesList Run MessagesA
Read-onlyIdempotent
Inspect

Get paginated messages for an agent run. Messages are returned in chronological order.

NameRequiredDescriptionDefault
limitNoNumber of messages per page (1-50, default 20)
offsetNoNumber of messages to skip
run_idYesThe run's unique identifier

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, and non-destructive behavior. The description adds useful behavioral details about pagination and chronological ordering, but it does not disclose response shape or behavior for invalid or missing run IDs. No contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler. It front-loads the core purpose and adds ordering behavior in the second sentence, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple, read-only listing tool with fully documented parameters and strong annotations, the description is nearly complete. It could be more complete by distinguishing itself from listCaseRunRecentMessages or noting the absence of a response schema, but those are minor gaps.

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?

The input schema has 100% description coverage for all three parameters, including limit, offset, and run_id. The description does not add any parameter-specific meaning beyond what the schema already provides, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (get), resource (messages), and scope (an agent run), and adds that results are paginated and chronological. It does not explicitly differentiate from sibling tools like listCaseRunRecentMessages, so it stops short of a perfect score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for retrieving messages belonging to a specific run, which provides basic usage context. However, it offers no explicit guidance on when to prefer this over related tools such as listCaseRunRecentMessages or listRuns, and no when-not-to-use information.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listRunsList RunsA
Read-onlyIdempotent
Inspect

List runs for the current team. Supports filtering by agent, user, queue, status, etc. Messages, evaluation data, and queue metadata are included where available. Set count_only=true to skip Run row selection and enrichment. The normal response shape is returned with data: [] and the matching total. To sweep a whole team, follow next_cursor rather than raising offset.

NameRequiredDescriptionDefault
limitNoNumber of runs per page (1-100, default 20)
sinceNoReturn runs completed at or after this ISO-8601 timestamp. Runs that have not completed are excluded.
untilNoReturn runs completed before this ISO-8601 timestamp. The upper bound is exclusive. Runs that have not completed are excluded.
cursorNoResume after the run a previous page ended on: pass the `next_cursor` that page returned, with the same filters and sort_order. Unlike offset, a cursor page does not re-read the runs before it, so a sweep does not slow down as it goes deeper; send `include_total=false` on the first page to skip the full count too. Runs created in between cannot shift a boundary already passed, so pages do not repeat or skip runs the way offset pages do. A run created or completed while a sweep is in progress can still be missed by that sweep, so to export runs continuously, poll with `since` and a short overlap and deduplicate on run id. Cannot be combined with `offset`. 400 when the value is not a valid runs cursor.
offsetNoNumber of runs to skip. Every skipped run is still read by the database, so deep offsets get slower page by page; to walk a whole team's history, page with `cursor` instead.
searchNoFull-text search across run titles and case titles
sourceNoFilter to runs created from this source (e.g. api, schedule)
statusNoFilter to runs with this status
sort_byNoField to sort by (default created_at)created_at
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
user_idNoFilter to runs owned by this user. Callers below Administrator, other than Lead Builders, are scoped to themselves regardless of this value, unless the request comes from a dashboard
agent_idNoFilter to runs for this agent
digest_idNo
count_onlyNoSkip row selection and enrichment. The normal list response shape is returned with an empty row array and the matching total.false
has_issuesNoFilter on the run's latest successful evaluation: true returns only runs it flagged, false only runs it did not. Only the latest evaluation counts — an older flag does not match — and a run whose latest evaluation errored, or that has none, counts as unflagged. Omit to return both.
sort_orderNoSort direction (default desc)desc
automation_idNoFilter to runs that ran under this automation. A run keeps the automation it was created under, even after its agent moves to another automation
case_queue_idNoFilter to runs associated with this queue
include_totalNoWhether to return `total`, the count of every matching run. Counting walks every match, so it costs far more than the page itself on a large team. Defaults to true on a first page and false on a `cursor` page, where `total` is null unless this is true. Implied by `count_only`.
issue_severityNoIf set, only return runs whose latest successful evaluation has at least one failing rubric with this severity (critical | medium | low). Implies has_issues; legacy evaluations without severity companion fields do not match this filter.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), so the bar is lower, and the description still adds genuinely new context: runs carry messages, evaluation data, and queue metadata 'where available,' and count_only short-circuits row selection with a 'data: []' plus total shape. With no output schema, this return-content disclosure is the only source of that information, though the cursor/offset guidance partly duplicates the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Five sentences, front-loaded with purpose and scope before filtering and pagination detail, with no filler. The count_only sentence restates schema content, but the text stays tight and each sentence is short.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 20-parameter read tool with 95% schema coverage and no output schema, the description covers purpose, scope, return content, and pagination strategy adequately. It leaves role-based scoping (user_id) to the schema and does not enumerate the full filter set, but nothing critical for correct invocation is missing.

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 95%, so the schema already documents all 20 parameters in depth; the description only gestures at filters ('agent, user, queue, status, etc.') and highlights count_only. That adds little beyond what the structured fields provide, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List runs for the current team') and gives a scope boundary ('current team') that implicitly separates it from listOrgRuns and listCaseRuns. It never explicitly names or routes to those siblings, so an agent must infer the distinction from the scope phrase alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers a capability list ('filtering by agent, user, queue, status, etc.') and a pagination strategy ('follow next_cursor rather than raising offset'), which is real usage guidance. But it gives no when-to-use/when-not-to-use guidance relative to siblings like listOrgRuns, listCaseRuns, or getRun, leaving selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSandboxFilesList Sandbox FilesB
Read-onlyIdempotent
Inspect

List files in a sandbox directory.

NameRequiredDescriptionDefault
pathNoDirectory to list files from (defaults to /workspace)/workspace
sandbox_idYesThe sandbox's unique identifier

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered elsewhere. The description adds no behavioral detail beyond the title, such as whether the listing is recursive, whether hidden files are included, or what the response contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no filler: it names the verb and the resource immediately. It is as concise as a simple list operation needs to be, even though other dimensions lack depth.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with complete parameter documentation and safety annotations, the description is nearly sufficient: an agent knows it needs a sandbox_id and can optionally pass a path. The absence of an output schema and the close sibling listFiles leave minor ambiguity, but the core call is fully determined by the schema and annotations.

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%, with sandbox_id documented as the sandbox's unique identifier and path documented as the directory to list with a default of /workspace. The description's phrase 'sandbox directory' only restates that context and adds no new parameter meaning, so the schema carries the load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action ('List') and a specific resource ('files in a sandbox directory'), so an agent can understand the basic function. However, it does not explicitly distinguish this tool from the sibling listFiles, which likely has overlapping behavior, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use listSandboxFiles versus listFiles, getFileContent, or uploadSandboxFile. The only hint is the word 'sandbox', which implies the tool is for sandbox-scoped file listing, but the intended selection criteria are not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSecretsList SecretsA
Read-onlyIdempotent
Inspect

List env-var secrets the caller can reach in this team — team-shared (user_id IS NULL), the caller's own personal entries, and secrets another team in the organization has granted to this team. Returns metadata and env-var keys only; secret values are never exposed.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so the description is freed to add value, and it does: it discloses the visibility model and the important security behavior that only metadata and env-var keys are returned, never secret values. That is meaningful context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the verb and scope, with the security caveat placed last. The parenthetical '(user_id IS NULL)' is slightly jargon-heavy but earns its place by defining what 'team-shared' means.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description compensates by stating exactly what is returned (metadata and env-var keys, not values). For a simple one-param read tool this is nearly complete, with only the alternative-routing guidance missing.

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 coverage is 100% and the single team_id parameter is fully documented in the schema, so the baseline is 3. The description reinforces the team-scoping but adds no format or fallback detail beyond the schema.

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?

States a specific verb and resource (list secrets) plus the exact scope: team-shared entries, the caller's personal entries, and org-granted secrets. This clearly separates it from getSecret (single) and listRevisionSecrets (a different namespace).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The described result scope implies when this tool applies, but there is no explicit routing to alternatives like getSecret or listRevisionSecrets, and no stated preconditions. Usage must be inferred from the visibility description rather than being spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSkillAssignmentsList Skill AssignmentsA
Read-onlyIdempotent
Inspect

List the agents in the current team whose live build references the given skill. Used to warn users that editing a skill will affect every agent that uses it.

NameRequiredDescriptionDefault
skill_idYesSkill ID.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds valuable context beyond these: the scope is the 'current team' (complementing openWorldHint=false by defining the closed-world boundary), and only 'live build' references count — an important nuance distinguishing current usage from draft or historical revisions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler. The core function is front-loaded in the first sentence, and the second sentence earns its place by explaining the tool's purpose in an agent's decision workflow. Every word contributes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with comprehensive annotations and 100% schema coverage, the description is nearly complete. It specifies scope, the meaning of the result, and when to use it. The only minor gap is the return format, which is not documented since there is no output schema — but 'List the agents…' makes the return shape reasonably inferable.

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 of 3 applies — the schema already documents skill_id as a UUID. The description reinforces the semantic ('the given skill' maps to skill_id) but adds no format or syntax details beyond what the schema provides.

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 states a specific verb ('List'), a specific resource ('agents in the current team'), and a precise qualifier ('whose live build references the given skill'). It defines what an 'assignment' means in this context, distinguishing it from sibling tools like listAgents, listTeamMembers, listSkillRevisions, and listSkills without needing their schemas.

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?

The second sentence provides a clear use case: 'Used to warn users that editing a skill will affect every agent that uses it.' This tells an agent when to call the tool (before editing/deleting a skill to assess impact). It doesn't explicitly name alternatives or exclusions, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSkillFilesList Skill FilesA
Read-onlyIdempotent
Inspect

List all files in a skill.

NameRequiredDescriptionDefault
skill_idYesSkill ID.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds that the result is the complete file set ('all files'), but does not disclose return shape, whether directories are traversed, or error behavior, which is a moderate gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single six-word sentence with no repetition or filler. Every word carries meaning and the core action is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only list operation with rich annotations, the description is mostly sufficient. However, with no output schema and a sibling named listSkillRevisionFiles, it would be stronger if it clarified whether it returns the current skill's files, metadata fields, or nesting details.

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?

The schema covers 100% of parameters and already documents skill_id as a UUID. The description adds no parameter-level meaning, so it stays at the baseline for fully covered schemas.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action and object: 'List all files in a skill.' It is unambiguous about the resource being listed, but it does not differentiate this tool from nearby siblings like listSkillRevisionFiles or listFiles, so it falls short of full separation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: use this when you need the file set for a skill. It does not explicitly state when to prefer it over listSkillRevisionFiles or how it differs from listFiles, so the guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSkillRevisionFilesList Skill Revision FilesA
Read-onlyIdempotent
Inspect

List the files in a skill revision, one page at a time. When has_more is true, pass next_cursor back as cursor to fetch the next page.

NameRequiredDescriptionDefault
limitNoMaximum number of files to return per page (1-1000, default 100)
cursorNoOpaque continuation token from a previous response's `next_cursor`. Omit for the first page.
skill_revision_idYesSkill revision ID.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the operation as read-only, idempotent, and non-destructive, lowering the burden on the description. The description adds meaningful behavioral context about the pagination contract, explaining how to use `has_more` and `next_cursor` to continue fetching pages.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The core operation is stated first, and the pagination detail that is essential to correct invocation is placed right after.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only paginated list tool, the description covers the essential return-related behavior by naming `has_more` and `next_cursor`. It doesn't describe the file object shape, but the lack of an output schema is partially mitigated by the simplicity of the operation and the clear resource being listed.

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?

The input schema provides 100% coverage, documenting all three parameters with descriptions, defaults, and constraints. The description mostly reiterates the cursor behavior already captured in the schema ('Opaque continuation token from a previous response's `next_cursor`'), so it adds little new semantic value.

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 states a specific verb ('List'), a specific resource ('files in a skill revision'), and adds pagination context ('one page at a time'). This clearly distinguishes it from siblings like listSkillRevisions (lists revisions) and listSkillFiles (lists files at the skill level).

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?

The description clearly conveys when to use this tool: when you need the files belonging to a specific skill revision. It doesn't explicitly name alternatives or exclusions, but the resource scoping ('in a skill revision') provides clear context for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSkillRevisionsList Skill RevisionsA
Read-onlyIdempotent
Inspect

List a skill's version history. Each revision is a snapshot of the skill's files; at most one is active (live) at a time, plus at most one open draft.

NameRequiredDescriptionDefault
limitNoNumber of revisions per page (1-100, default 20)
offsetNoNumber of revisions to skip
skill_idYesSkill ID.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint false, so the safety profile is covered. The description adds valuable non-obvious context about revision semantics: each revision is a file snapshot, and there is at most one active/live revision and one open draft. This goes meaningfully beyond the structured annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no wasted words. The primary action is front-loaded, and the second sentence earns its place by explaining the revision/live/draft model that is essential to understanding the result.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only list tool with strong annotations and complete parameter documentation, the description conveys the essential output concept: a version history of file snapshots with at most one live revision and one open draft. It leaves minor details implicit, such as sort order and whether the draft appears in the paginated list, but these are not significant enough to make the tool hard to call correctly.

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%, with skill_id, limit, and offset all documented in the schema. The description does not add parameter-level detail, but it does not need to because the schema fully explains the parameters. Baseline 3 is appropriate.

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 clearly states the verb ('List') and the resource ('a skill's version history'), then explains what a revision is: a snapshot of the skill's files with at most one live revision and one open draft. This uniquely distinguishes it from sibling tools like listSkillRevisionFiles, which list files inside a revision, and getRevision, which retrieves a specific revision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit when-to-use or when-not-to-use guidance is provided. There is no mention of alternatives such as getRevision or listSkillRevisionFiles, nor any conditions under which this tool should be chosen over them. The domain context implies a listing use case, but an agent must infer the routing decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSkillsList SkillsA
Read-onlyIdempotent
Inspect

List all skills for the current team, including system skills.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds the 'current team' scope and inclusion of system skills, which is useful context beyond annotations, but it does not address output format or pagination.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short, focused sentence that front-loads the action and scope. Every word earns its place; there is no redundant filler.

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 single-optional-parameter, read-only list tool with complete schema documentation and safety annotations, this description is sufficient. It tells the agent what will be listed and the special inclusion of system skills, and no output schema is needed for a simple list operation.

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%: the team_id parameter is already thoroughly documented with fallback and restriction behavior. The tool description adds no extra parameter semantics beyond mentioning 'current team,' so the baseline of 3 is appropriate.

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?

Description uses a specific verb ('List') and resource ('all skills for the current team'), and the phrase 'including system skills' sharpens scope against sibling tools such as listSystemSkills. An agent can tell what this tool returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to prefer this tool over alternatives; sibling listSystemSkills exists and is not referenced. The description only implies a generic listing use case, and the team_id parameter description covers team selection rather than tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listSystemSkillsList System SkillsA
Read-onlyIdempotent
Inspect

List all system skills (skills available to all teams).

NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already disclose readOnlyHint, idempotentHint, and destructiveHint, which cover the safety profile. The description adds the scoping context that the tool returns system-wide skills consistent with openWorldHint=false, but it discloses no additional behavioral traits such as pagination, ordering, or return shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the verb and resource, followed by a compact parenthetical that adds disambiguating scope. Every word earns its place with negligible waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameter-less, read-only list operation, the description plus annotations are nearly sufficient. The only gap is unspecified return properties or pagination, but the trivial complexity makes this a minor omission.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema is empty with zero parameters, so there is nothing for the description to clarify. Baseline 4 applies for parameter-less tools.

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 uses a specific verb ('list') and resource ('system skills'), and the parenthetical defines system skills as 'skills available to all teams,' which disambiguates it from close siblings such as listSkills, listSkillAssignments, and listSkillRevisions. An agent can distinguish this tool without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical gives implicit usage context — use this when you want skills available to all teams. However, no alternative tool is named and no explicit when-not-to-use guidance is given, so routing among the many skill-related siblings is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listTeamInvitesList Team InvitesA
Read-onlyIdempotent
Inspect

List a team's pending invitations — everyone invited who has not yet accepted or declined. Pass processId to list the pending invitations for a single Clarity process instead.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
processIdNoList the pending invitations for this Clarity process instead of the team's own invitations. Requires the process creator or a team admin.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, so the safety profile is covered. The description adds useful scoping semantics (pending-only, processId override), but does not disclose pagination, response shape, or permission nuances beyond what the schema already provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences with the main action front-loaded and the alternative invocation clearly stated. Every word earns its place, with no redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list operation with zero required parameters and rich parameter schemas, the description is mostly complete. It does not describe return fields or pagination, which would be useful given there is no output schema, but an agent has enough to invoke the tool correctly.

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 both parameters are already well documented in the schema. The description adds a helpful 'instead' framing for processId but does not materially go beyond the schema's parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb and resource: list a team's pending invitations, and defines 'pending' as not yet accepted or declined. It also distinguishes the processId-scoped variant. However, it does not explicitly differentiate this tool from sibling tools like listTeamMembers or getTeamInviteLink.

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?

The description gives clear usage context: list pending team invitations, or pass processId to list pending invitations for a single Clarity process. It does not explicitly state when not to use this tool or name alternative list tools, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

listTeamMembersList Team MembersA
Read-onlyIdempotent
Inspect

List members of a team. The authenticated session or API key must be scoped to the requested team.

NameRequiredDescriptionDefault
limitNoNumber of members per page (1-100, default 50)
offsetNoNumber of members to skip
searchNoOptional case-insensitive name or email search
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds meaningful behavioral context by requiring the authenticated session or API key to be scoped to the team, which is a real constraint beyond what annotations express. It does not describe return values or error behavior, but the annotations carry most of the safety burden.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence with no wasted words. It states the core action first and the auth precondition second, making it easy for an agent to parse quickly.

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 low-complexity list operation, the description combined with the fully documented schema and safety annotations is sufficient for correct invocation. There is no output schema, but 'list members of a team' adequately signals that the result is a member list. Nothing critical is missing.

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%, and the schema itself already provides detailed parameter semantics, including the nuanced team_id guidance for API keys versus OAuth callers. The description only adds a general auth-scoping requirement and does not elaborate on limit, offset, or search beyond what the schema already documents. Baseline 3 is appropriate when the schema handles parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('List') and resource ('members of a team'), making the tool's purpose immediately understandable. It is distinguishable from mutation siblings like removeTeamMember and updateTeamMemberRole by being a read operation, but it does not explicitly name or contrast any sibling tools.

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?

The description gives clear context: this tool lists team members. It also provides a practical precondition — the session or API key must be scoped to the requested team — which helps an agent decide whether the call can succeed. It does not mention alternative tools, but the operation is simple enough that no exclusions are necessary.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

markAllNotificationsReadMark All Notifications ReadA
Idempotent
Inspect

Mark all notifications as read for the authenticated user's current team. Returns the count of notifications that were updated. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=false and idempotentHint=true, which the description does not contradict. The description adds value beyond annotations by disclosing the return value (count of updated notifications), the 404 failure mode when the feature is disabled, and the team-scoping constraint. No annotation contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with zero filler. The action is front-loaded, followed by the return value, then the feature prerequisite. Each sentence earns its place; the description is compact and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-optional-parameter tool with 100% schema coverage and safety annotations, the description covers action, scope, return value, and error condition. The only minor gap is a slight ambiguity about whether 'all notifications' means all of the user's notifications within the team or all team notifications, and it does not mention related read-state tools. Otherwise, nothing needed for a correct call is missing.

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 coverage is 100%: the team_id parameter already carries a rich description (API key pinning, OAuth multi-team behavior, fallback and rejection rules). The tool description adds mild framing by referencing 'the authenticated user's current team,' but the schema does the heavy lifting for parameter semantics. Baseline 3 is appropriate.

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 states a specific verb ('mark') and resource ('all notifications') with an explicit scope ('the authenticated user's current team'). The word 'all' inherently distinguishes it from siblings markNotificationRead and markNotificationBatchRead, and 'mark as read' distinguishes it from deleteAllNotifications/deleteReadNotifications. Purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear precondition ('Requires the Notification Center feature; returns 404 when not enabled') that tells an agent when the tool is available, and the scope ('current team') frames when it applies. However, it does not explicitly name alternatives or give when-not-to-use guidance (e.g., when a batch subset is preferred over all notifications). Usage context is implied rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

markNotificationBatchReadMark Notification Batch ReadA
Idempotent
Inspect

Mark every unread live member of a notification batch as read for the authenticated user. Pass types to narrow the mark-read to those member types, and severity (exact) or minSeverity (threshold, mutually exclusive with severity) to narrow it by urgency — e.g. the page's active filters; omit them to mark every live member. Narrowing matters when the batch card was rendered under a filter: the rows marked read should be the rows the card counted. Pass openedFrom to record which channel the reader came through, on every member this call marks read. Returns the count of members that were updated. Requires the Notification Center feature; returns 404 when it is not enabled for the team or the batch does not exist or belongs to another recipient/team.

NameRequiredDescriptionDefault
idYesThe notification batch's unique identifier
typesNo
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
severityNo
openedFromNo
minSeverityNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the mutation/idempotent/non-destructive profile, so the description is not carrying the safety burden. It adds genuinely useful behavioral context beyond them: the return value (count of updated members), the Notification Center feature dependency, the exact 404 conditions, and the side effect that openedFrom is stamped on every member marked.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action is front-loaded in the first sentence, followed by parameter-scoping rules and error conditions in a logical order. It is dense rather than padded, though a couple of clauses (the 'e.g. the page's active filters' aside) are mildly verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter mutation with no output schema, the description covers the essentials: what gets updated, what narrowing does, the return count, feature gating, and 404 failure modes. Nothing critical for correct invocation appears missing, though it could note whether already-read members are excluded from the returned count.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 33% schema description coverage, the description compensates well: it clarifies that severity is exact while minSeverity is a threshold and that the two are mutually exclusive, explains that types narrows the mark to member types, and defines openedFrom as the channel recorded on every newly read member. The id/team_id behavior is left to the schema, but the substantive gaps are covered.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource — mark every unread live member of a notification batch as read for the authenticated user — which is far more precise than the title restatement. It is implicitly distinguishable from markNotificationRead and markAllNotificationsRead via the 'batch' scope, but it never names those siblings explicitly, so a 4 rather than a 5.

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 when-to-narrow guidance ('pass types to narrow', 'omit them to mark every live member') and explains the rationale ('the rows marked read should be the rows the card counted'). It does not, however, contrast this with the single-notification or mark-all siblings, leaving that routing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

markNotificationReadMark Notification ReadA
DestructiveIdempotent
Inspect

Mark a notification as read for the authenticated user. Idempotent — calling it again on an already-read notification still returns success. Pass openedFrom to record which channel the reader came through (in_app when they were already in Duvo, or email/slack/teams from the notificationSource param on an external link); omit it when the read is not somebody opening the notification. Requires the Notification Center feature; returns 404 when it is not enabled for the team.

NameRequiredDescriptionDefault
idYesThe notification's unique identifier
openedFromNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the annotations by disclosing idempotent behavior explicitly ('calling it again on an already-read notification still returns success'), the feature dependency (Notification Center), and the 404 failure mode when it is disabled. It does not explain the destructiveHint=true annotation, though for a mark-as-read operation that is largely self-evident.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action in the first sentence and layers on idempotency, parameter guidance, and the feature/error constraint in a tight, well-ordered block. Dense but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the operation, its idempotency, the parameter contract, and the 404 failure condition, which is sufficient given there is no output schema. It stops short of describing any success payload shape, but the description explicitly says it returns success, which is enough for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema only names `openedFrom` without describing it; the description supplies the meaning (the channel the reader came through), the value semantics, the relationship to `notificationSource` on external links, and the omission condition. This substantially compensates for the 50% schema coverage.

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?

States a specific verb (mark as read) and resource (a single notification) scoped to the authenticated user. It is clearly distinguishable from sibling tools markAllNotificationsRead and markNotificationBatchRead by virtue of operating on one notification.

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?

Gives explicit guidance on when to supply `openedFrom` versus when to omit it, and ties the enum values to the reader's entry channel. It does not, however, name the sibling alternatives (markAllNotificationsRead, markNotificationBatchRead) or state when one should be preferred over this one.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

moveAgentMove AgentAInspect

Move an agent (and its connected workspace) to a different team. Pass dry_run=true to preview the closure without applying changes.

NameRequiredDescriptionDefault
dry_runNoWhen true, preview the closure and warnings without applying any changes.
agent_idYesThe ID of the agent to move.
target_team_idYesThe ID of the team to move the agent into.
bypass_standalone_gateNoWhen true, move the agent together with every connected queue, trigger, and handover peer instead of rejecting a non-standalone agent. Defaults to false.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds meaningful behavior beyond annotations by revealing that the connected workspace is moved and that the operation involves a 'closure' that can be previewed with dry_run. Annotations already signal mutation through readOnlyHint=false, and the description enriches this with concrete side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with no filler. The core action is front-loaded, and the dry-run guidance is placed second as a natural follow-up. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with full schema coverage and annotations, the description gives enough context: what is moved, what to preview, and that the operation can be dry-run. It does not explain return values or deeper closure consequences, but the absence of an output schema and the presence of the bypass_standalone_gate parameter in the schema make this acceptable.

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 schema fully documents all four parameters. The description mentions dry_run=true but does not add meaning beyond the schema. Baseline 3 is appropriate because the structured data already carries the parameter semantics.

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 names a specific action ('Move'), a specific resource ('an agent and its connected workspace'), and the target ('to a different team'). This clearly differentiates it from siblings like moveAgentsToFolder or movePulseDashboard.

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?

The description gives clear operational context: moving an agent to a different team affects the connected workspace. It also provides a direct usage hint for dry_run=true. It does not explicitly enumerate alternatives or when-not-to-use, but the core use case is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

moveAgentsToFolderMove Agents To FolderAInspect

Move one or more agents (assignments) into a folder, or to the root level.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
agent_idsYesIDs of the agents (assignments) to move. Must be unique.
folder_idYesDestination folder ID. Pass null to move the agents to the root level.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal a non-read-only mutation that is not destructive or idempotent. The description adds the specific move behavior and the root-level option, but does not disclose side effects such as leaving the previous folder or permissions required.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that states the action, target, and destination options with no filler. It is concise and immediately scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a straightforward move operation with fully self-describing parameters, the description plus schema provides enough to invoke correctly. It omits return-value details, but no output schema exists and the operation is simple enough that this is a minor gap.

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 coverage is 100%: each parameter has a meaningful description, including the null meaning of folder_id. The tool description adds no parameter-level details beyond what the schema already provides, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb (move), resource (agents/assignments), and destination (folder or root level). It is unambiguous, though it does not explicitly differentiate from the similarly named sibling moveAgent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage context is implied by the operation—use it when agents need to be placed into a folder or moved back to root—but no alternatives or when-not-to-use conditions are mentioned, despite relevant siblings like moveAgent and moveClarityProcessesToFolder.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

moveAutomationsToFolderMove Automations To FolderAInspect

Move one or more automations into an agent folder, or to the root level.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
folder_idYesDestination folder ID. Pass null to move the automations to the root level.
automation_idsYesIDs of the automations to move. Must be unique.

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description communicates that this is a move operation, including the root-level special case, which is useful beyond the bare tool name. Annotations already indicate readOnly=false and destructiveHint=false, and the description adds limited additional behavioral context such as failure modes, validation, or effects on existing folder membership.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that clearly states the action, the target, and the root-level exception. There is no unnecessary information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple move tool, the description plus the detailed input schema is largely sufficient. It covers the batch nature ('one or more automations') and the root-level destination, though it does not describe prerequisites like folder existence or what happens if an automation is already in the target folder.

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 parameters are already well documented. The description's mention of 'root level' aligns with the folder_id schema but does not add meaning beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Move' with a clear resource ('automations') and destination ('agent folder' or 'root level'). It is easily distinguishable from sibling tools like moveAgentsToFolder and moveClarityProcessesToFolder by the resource type, though it does not explicitly name those alternatives.

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?

The description gives clear context: use this tool when moving one or more automations into an agent folder or to the root level. It does not explicitly list exclusions or alternative tools, but the resource-focused wording makes the intended use unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

moveClarityProcessesToFolderMove Clarity Processes To FolderAInspect

Move processes into a folder (or back to Unfiled)

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
folderIdYesDestination folder ID, or null to move back to Unfiled.
processIdsYesClarity process IDs to move.

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is a write operation (readOnlyHint=false) and non-destructive (destructiveHint=false). The description adds the 'back to Unfiled' behavior, which is useful, but it does not disclose side effects such as the process being removed from its previous folder or behavior when some processIds are invalid. No annotation contradiction exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no filler. It conveys the primary operation and the key Unfiled exception in very few words, making it easy for an agent to parse quickly.

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 simple bulk-move operation with fully self-documenting parameters and no output schema, the description is complete enough. It states the action, the target, the special Unfiled case, and the schema covers the remaining invocation details.

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%, with detailed descriptions for processIds, folderId, and team_id, including the null-to-Unfiled behavior. The tool description adds no extra parameter meaning beyond what the schema already provides, so the baseline score of 3 is appropriate.

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 uses a specific verb and resource: 'Move processes into a folder (or back to Unfiled)'. It clearly distinguishes this tool from sibling move tools like moveAgentsToFolder and movePulseDashboard by naming Clarity processes, and it adds the important edge case of moving back to Unfiled.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage well enough for a self-named operation, but it does not explicitly say when to prefer this over related tools such as updateClarityFolder or reorderClarityFolders, nor does it mention that folder IDs come from listClarityFolders. There are no exclusions or alternative routing hints.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

movePulseDashboardMove Pulse DashboardA
Destructive
Inspect

Move a Pulse dashboard from the team in the URL to another team, keeping only its latest revision (chat history and older revisions are deleted). The caller must be a Manager or above on both teams. Pass dryRun=true to preview which Connections reconnect vs drop without applying changes.

NameRequiredDescriptionDefault
dryRunNoWhen true, only previews the move: reports which Connections would reconnect vs drop without changing anything.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
artifactIdYes
targetTeamIdYesID of the destination team the dashboard moves to.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses exactly what is destroyed (chat history and older revisions), the authorization requirement on both teams, and the dryRun preview semantics (which Connections reconnect vs drop). For a destructive mutation this is exactly the behavioral context an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the action, then destructiveness, then auth, then the preview option. No filler and each clause carries decision-relevant information.

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 destructive, non-idempotent move with no output schema, the description covers what is lost, who may perform it, and how to dry-run it. Nothing an agent needs before calling is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75% and dryRun already has a schema description, but the description adds the concrete 'reconnect vs drop' outcome that the schema only states abstractly. The phrase 'the team in the URL' is slightly confusing for the team_id source param and artifactId remains undocumented, keeping it below a 5.

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?

Specific verb (move) plus specific resource (Pulse dashboard) with clear source→destination framing. An agent can distinguish this from siblings like duplicatePulseDashboard, updatePulseDashboard, and restorePulseDashboardVersion without opening any schema.

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?

Gives a clear use context plus the permission precondition (Manager or above on both teams) and points to dryRun for preview. It does not name alternative siblings such as duplicatePulseDashboard for agents who may want a copy rather than a move, so it falls short of explicit when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

organizeClarityProcessLandscapeOrganize Clarity Process LandscapeAInspect

Start an asynchronous organization pass over the organization's unfiled processes, placing them into the Process Landscape where possible (organization admin+). Results appear progressively; started is false when there is nothing to organize.

NameRequiredDescriptionDefault
orgIdYes
instructionsNoDeprecated: ignored. The organize pass takes no instructions.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal a mutating, non-idempotent operation, so the description adds valuable context by disclosing async execution, progressive results, and the 'started is false when there is nothing to organize' edge case. It also surfaces the admin+ permission gate. No contradiction with annotations is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the action and scope, followed by the async and result behavior. There is no filler, no repetition of schema fields, and every clause contributes useful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating tool with no output schema, the description covers the core action, admin permission, async execution, progressive appearance of results, and the meaningful false-start condition. It could specify how to observe progress or handle concurrent passes, but the provided context is sufficient for correct invocation.

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?

The schema documents instructions as deprecated/ignored but leaves orgId with only format and pattern. The description indirectly clarifies orgId as the target organization by referring to the organization's unfiled processes, but it does not explicitly map either parameter or provide additional semantic detail beyond the schema.

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 action ('Start an asynchronous organization pass'), names the resource ('the organization's unfiled processes'), and states the destination ('placing them into the Process Landscape'). This clearly distinguishes it from sibling get/generate/propose landscape tools by framing it as an organizing operation rather than a read or generation operation.

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 provides clear context: use this when you want to organize unfiled processes into the Process Landscape, and it flags the admin+ permission requirement. It does not explicitly name alternative tools or state when not to use it, so exclusion guidance is left somewhat implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

pinRevisionIntegrationConnectionPin Revision Integration ConnectionAInspect

Pin one of your connections (from GET /v2/teams/:team_id/connections) to this build's integration slot. Multi-pin is supported: a single user can pin multiple connections to the same slot.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID
connection_idYesID of one of your connections (from GET /v2/teams/:team_id/connections) to pin to this slot
integration_idYesIntegration ID (catalog integration ID or slot ID from the list response)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds a valuable behavioral detail not present in the annotations: multi-pin is supported, meaning a single user can pin multiple connections to the same slot. This helps set expectations about non-replacement behavior. The annotations already signal a write operation and non-destructive behavior, and the description is consistent with those signals.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. It front-loads the core action, then adds the most important behavioral nuance, multi-pin support. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple pin operation with four required parameters, the description plus schema provide enough context to invoke the tool correctly. It explains the source of connections, the target slot, and the key behavioral twist. The lack of an output schema is not a significant gap here, though it does not describe what happens to existing pins beyond implying coexistence through multi-pin support.

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 schema already documents all four parameters. The description reinforces where connection_id comes from and what an integration slot is, but it does not add new semantic detail beyond the schema. This is an adequate baseline case where structured information carries the weight.

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 states a specific verb (pin), a specific resource (connection), and a clear target (build's integration slot), while also specifying the source of valid connections via the GET endpoint. This clearly distinguishes it from siblings like unpinRevisionIntegrationConnection and listRevisionIntegrationConnections. It adds meaningful detail beyond the title by explaining what is pinned and where.

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?

The description gives clear context for when to use the tool: when pinning an existing connection to a build's integration slot, and it even tells the agent where to obtain valid connection IDs. It does not explicitly discuss alternatives or exclusion conditions, but the intended usage is unambiguous enough for an agent to select this tool correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

postprocessClaritySnapshotPostprocess Clarity SnapshotAInspect

Re-run postprocessing agents on an existing v2 clarity snapshot. Targets either the current-process snapshot or the automation proposal snapshot, identified by id in the body. Flips the process status to generating and returns 202 immediately; agents run asynchronously and flip the status back to review once they settle.

NameRequiredDescriptionDefault
typeYesThe snapshot kind to post-process.
process_idYesThe clarity process id
current_process_idNoRequired when type is `current_process`.
transformation_proposal_idNoRequired when type is `transformation_proposal`.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations by disclosing key behavioral traits: it flips the process status to `generating`, returns 202 immediately, and runs agents asynchronously before flipping the status back to `review`. This gives an agent a clear model of the side effects and async behavior without contradicting the readOnlyHint=false annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three focused sentences: the action is front-loaded, followed by the target scope, then the async behavior. There is no filler or redundant repetition of schema information. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core action, target selection, immediate 202 response, and asynchronous completion behavior. With no output schema, it omits return-value specifics but provides enough for an agent to understand the operation's flow. The exact conditional id mapping is left to the schema, which fully documents it, so nothing critical is missing.

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 coverage is 100%, so the baseline is 3. The description adds some semantic grouping by naming the snapshot kinds, but it uses 'automation proposal' where the schema enum says 'transformation_proposal,' and it vaguely refers to 'identified by id in the body' without mapping ids to types. The parameter details are essentially carried by the schema, not the description.

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: 'Re-run postprocessing agents on an existing v2 clarity snapshot.' It further narrows the target to either the current-process snapshot or the automation proposal snapshot. This clearly distinguishes it from sibling snapshot operations like generateClarityProcessSnapshot, promoteClarityProcessSnapshot, saveClarityProcessSnapshot, revertClarityProcessSnapshot, and stopClarityProcessSnapshot.

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?

The description clearly states the use case: when you need to re-run postprocessing agents on an existing snapshot, and it identifies the two snapshot types it can target. However, it does not explicitly mention alternatives or provide 'when not to use' guidance, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

postRunMessagePost Run MessageAInspect

Post a message to an agent run. This will persist the message and resume the agent execution if the run is completed or interrupted and has no pending human request. A run whose workspace data retention deleted answers 410 with code sandbox_expired.

NameRequiredDescriptionDefault
run_idYesThe run's unique identifier
messageYesThe message content to send to the agent

TDQS

A4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses key side effects: the message is persisted, and the agent execution resumes if the run is completed/interrupted and has no pending human request. It also documents a specific failure mode, HTTP 410 with code sandbox_expired when workspace data retention has deleted answers. This is meaningful behavioral context not available from the annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loaded with purpose, followed by the resume behavior and the 410 failure case. Every sentence carries useful information and there is no redundant repetition of the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter write tool with full schema coverage and annotations covering safety/idempotency, the description is mostly complete: it explains the core action, resume behavior, and a notable 410 error. One minor gap remains around what happens when a human request is pending, but this is a small omission rather than a major ambiguity.

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%, and both parameters are documented in the schema. The description adds no additional semantics about run_id or message beyond what the schema already provides, so the baseline score of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Post a message to an agent run.' It also clarifies that the message is persisted and may resume execution. It does not explicitly name or contrast with siblings such as listRunMessages or respondToHumanRequest, so it falls short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the purpose and by the resume condition: the agent will resume only if the run is completed or interrupted and has no pending human request. However, the description does not explicitly say when to use this instead of alternatives like respondToHumanRequest, nor does it clearly state whether posting is allowed while a human request is pending.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

previewAgentCaseTriggerConflictsPreview Agent Case Trigger ConflictsA
Read-onlyIdempotent
Inspect

Preview which other agents would conflict with this agent's case trigger if it pointed at the given queue. Does not modify the trigger.

NameRequiredDescriptionDefault
agent_idYesThe agent's unique identifier
case_queue_idYesThe queue to check for conflicts against

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and idempotentHint=true. The description reiterates 'Does not modify the trigger,' which is redundant but consistent. It adds the context of the hypothetical queue check but does not disclose return format or potential side effects beyond what annotations cover.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences that front-load the primary purpose and immediately clarify non-modification. No wasted words; the description is tightly scoped and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only preview tool with two UUID parameters and no output schema, the description conveys the essential behavior and outcome (returns conflicting agents). It could mention the return format or any prerequisites (e.g., whether the agent must already have a trigger), but given the annotations and simplicity, it is largely sufficient.

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 coverage is 100% with both parameters having clear descriptions (e.g., 'The agent's unique identifier' and 'The queue to check for conflicts against'). The tool description adds no additional semantic meaning beyond the schema, so the baseline of 3 applies.

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 states a specific verb ('Preview') and resource ('agent case trigger conflicts') and clarifies the hypothetical condition ('if it pointed at the given queue'). It distinguishes from create/update/delete triggers by explicitly noting it does not modify the trigger, making the purpose unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies a planning use case ('Preview which other agents would conflict') but does not explicitly name alternatives or state when to use this vs. creating/updating a trigger. It says 'Does not modify the trigger' which hints at non-destructive intent, but lacks direct comparison to sibling tools like createAgentCaseTrigger.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

probeMcpServerProbe an MCP server for available toolsAInspect

Probe an MCP server URL and list the tools it exposes. Useful as a dry-run before creating a connection — verifies the URL is reachable, that authentication headers (if any) are correct, and surfaces the tool catalog. Performs no writes; sits alongside /v2/teams/:team_id/connections/oauth/mcp/check (which probes the same URL for OAuth support).

NameRequiredDescriptionDefault
headersNoOptional HTTP headers for authentication (raw server_url mode only)
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
server_urlNoRaw MCP server URL to probe (for custom MCP servers)
integration_slugNoCatalog integration slug. The backend resolves the MCP server URL and dummy auth headers server-side — no server_url or headers needed.

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description does add real context beyond the annotations — it verifies reachability, checks that auth headers are correct, and returns the tool catalog. However, the claim 'Performs no writes' conflicts with readOnlyHint=false, an annotation explicitly stating the tool is not read-only; the agent receives two opposing signals about the tool's mutating side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three front-loaded sentences with the core purpose first and no filler. The trailing parenthetical about the internal REST path is informative for routing but is internal plumbing an agent doesn't strictly need, which keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 100% schema coverage but no output schema, the description adequately states what is returned ('surfaces the tool catalog') and the dry-run intent. It omits failure behavior (unreachable URL, bad headers) and any rate/network-egress caveats, which would matter for an open-world network tool.

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 schema already documents team_id pinning, the headers/raw-URL mode, and the integration_slug enum. The description only echoes 'authentication headers (if any)' and 'URL', adding no syntax or mode-selection detail beyond what the schema provides — the baseline 3 for high-coverage schemas.

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?

Specific verb + resource + outcome: 'Probe an MCP server URL and list the tools it exposes.' The agent knows exactly what comes back (a tool catalog). It also distinguishes itself from the neighboring OAuth-check endpoint, so it is routable against siblings like checkMcpOAuth and createConnection.

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?

'Useful as a dry-run before creating a connection' gives a clear when-to-use context and the description explicitly contrasts it with the OAuth probe. It falls short of 5 only because it points at a REST path (/v2/teams/.../oauth/mcp/check) rather than naming the sibling MCP tool (checkMcpOAuth) an agent would actually call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

promoteClarityProcessSnapshotPromote Clarity Process SnapshotA
Destructive
Inspect

Promote a draft or historic Clarity v2 snapshot to live for its kind.

NameRequiredDescriptionDefault
kindYesSnapshot kind to list
process_idYesThe clarity process id
snapshot_idYesSnapshot id

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructive=true, idempotent=false, and readOnly=false, so the safety profile is covered. The description adds that the source may be a draft or historic snapshot and the target is live, but it does not say what prior live state is replaced, whether the change is reversible, or what permissions are needed — useful context but not rich disclosure for a destructive mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. Every word contributes to stating the action, source scope, and target state.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent mutation with no output schema, the description states the operation but omits side effects such as what happens to the existing live snapshot and any prerequisites. Annotations and schema cover safety and parameters, so it is usable but not fully complete.

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 schema already documents process_id, snapshot_id, and the kind enum values. The description adds only the phrase 'for its kind', which does not extend parameter meaning beyond what the schema provides; baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('Promote'), resource ('Clarity v2 snapshot'), and scope ('draft or historic ... to live for its kind'). It implicitly distinguishes itself from siblings like generate/save/revert by the promotion action, but does not explicitly name an alternative or boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool — to move a draft or historic snapshot to live — but gives no when-not guidance, prerequisites, or routing to alternatives such as revertClarityProcessSnapshot. The agent must infer the context from the operation name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

promoteRevisionPromote RevisionA
Destructive
Inspect

Promote a draft or historic revision to the live version. The live revision is the one used by triggers and new runs. Fails if the revision is already live, or if a draft revision still has an active builder run.

NameRequiredDescriptionDefault
build_idYesThe build's unique identifier
revision_nameNoOptional display name to set on the promoted revision.
revision_descriptionNoOptional description for the promoted revision. Pass null to clear an existing description.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, but the description adds genuine context beyond them: it explains the consequence of the operation (the promoted revision becomes the one used by triggers and new runs) and the two failure modes. It stops short of stating that the previous live revision is replaced/lost, which is the one destructive detail still left implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the action, then the definition of the target state, then the failure conditions. No filler; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter mutation tool with no output schema and annotations covering the safety profile, the description supplies what it does, what 'live' implies, and failure preconditions. The main gap is not spelling out that the existing live revision is superseded, and no note on permissions/return behavior.

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 build_id, revision_name and revision_description are already fully documented in the schema. The description adds no parameter-level detail (no format, no defaulting behavior), so baseline 3 is appropriate.

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?

States a specific verb (promote) and resource (a draft or historic revision) with a clear target (the live version), and immediately defines what 'live' means so the agent can distinguish this from sibling operations like createRevision or updateRevision. It is unambiguous about the direction of the state change.

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?

The description gives clear context for use (promoting a draft or historic revision to live) and two explicit when-not conditions via the failure cases (already live, active builder run on the draft). It does not name alternative tools or state prerequisites, so it falls short of the explicit alternatives expected at 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

promoteSkillRevisionPromote Skill RevisionA
DestructiveIdempotent
Inspect

Make a skill revision the active (live) one. The previously active revision becomes historic and can be re-activated later. Idempotent: promoting the already-active revision succeeds rather than erroring, and still applies any revision_name / revision_description supplied in the body.

NameRequiredDescriptionDefault
revision_nameNoOptional display name to set on the promoted revision.
skill_revision_idYesSkill revision ID.
revision_descriptionNoOptional description for the promoted revision. Pass null to clear an existing description.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description still adds genuine value by disclosing that the previously active revision becomes historic and can be re-activated, plus the specific idempotent behavior that name/description are still applied. It does not mention auth requirements or response shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the core action, followed by the state-transition consequence and the idempotency edge case. No filler and no repetition of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter mutation with no output schema, the description covers the key behavioral concerns: what changes, reversibility of the previous revision, and idempotency. It omits permission/authorization context and any indication of the response, but no output schema exists so return-value detail is not required.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description goes beyond the schema by explaining that revision_name and revision_description are applied even when the promotion is a no-op idempotent call, which is meaningful semantic context the schema does not convey.

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?

States a specific verb and resource ('Make a skill revision the active (live) one') and clarifies the resulting state change. An agent can distinguish this from updateSkillRevision, createSkillRevision, or the generic promoteRevision without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains the state transition and the idempotent edge case, which implicitly tells the agent when the call is safe to make. However, it never states when to prefer this over siblings like updateSkillRevision or promoteRevision, nor any prerequisites such as required permissions. Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

proposeClarityLandscapeProcessPropose Clarity Landscape ProcessBInspect

Create a manual process in the organization's Process Landscape, either as an unassigned proposal or atomically assigned to an eligible team.

NameRequiredDescriptionDefault
nameYes
orgIdYes
teamIdNo
parentIdNo
descriptionNoOne short paragraph (1-3 sentences) saying why this process belongs in the landscape. Use only what you saw in the captures. Say what the process is (don't just repeat the name), show proof it really happens, and name where you heard it - be as specific as the captures allow, like "a warehouse lead said so in their interview" or "it came up in two returns recordings". Use only facts from the captures: never make up sources, people, dates, quotes, or numbers, and don't stretch what was said. If you have no real proof the process happens, don't propose it.
materializationModeNoUse "proposal" to record a process the organization plausibly needs, owned by `teamId` for review, WITHOUT creating a real process record. `teamId` is then required. Chat-scoped callers may only propose for their pinned team; every caller needs Manager-or-above authority for that team. A proposal is idempotent: an equivalent live proposal under the same parent is returned untouched rather than duplicated. Defaults to "auto", which materializes a real process when `teamId` is set.

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the non-read-only, non-destructive profile, so the bar is lower. The description adds one real behavioral trait beyond them: the assignment happens 'atomically', meaning the process and team binding are created together or not at all. It does not mention permission requirements, validation/naming rules, or what a proposal record looks like versus a real process.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single tightly-wrapped sentence with no filler and the primary action front-loaded. It is efficient, though it spends its only clause on mode enumeration rather than on disambiguation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter mutation tool with no output schema and sparse schema descriptions, the description is thin: it omits permissions, idempotency of proposals, hierarchy placement via parentId, and what is returned. Most of the operative detail sits in one parameter's schema text rather than in the tool description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33%: orgId, teamId, parentId and name are bare UUID/string fields. The description names no parameters and does not explain the teamId/parentId relationship or that teamId is required for proposal mode, so it fails to compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ('Create') plus a specific resource ('manual process in the organization's Process Landscape') and the two creation modes. It is clear what the tool does, but it never distinguishes itself from the close siblings createClarityProcess, createClarityLandscapeNode, or fileSuggestedClarityProcesses, leaving the agent to infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'either as an unassigned proposal or atomically assigned to an eligible team' implies the two usage modes, and the authority/pinning rules live in the materializationMode schema description rather than here. There is no explicit statement of when to prefer this over createClarityProcess, and no prerequisites or when-not guidance in the description itself.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

publishPulseDashboardPublish Pulse DashboardAInspect

Publish (share) a Duvo Pulse dashboard to your whole team or your whole organization, or revert it to private (creator only). When publishing, set permission to 'view' (teammates see the dashboard) or 'edit' (teammates can also iterate on it); organization-wide viewers outside the team always get view-only access.

NameRequiredDescriptionDefault
artifactIdYes
permissionNo
visibilityYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations only declaring the operation mutates (readOnlyHint=false) without being destructive, the description adds meaningful constraints: organization-wide viewers always receive view-only access regardless of the permission value, and 'private' means creator-only. It also clarifies that the permission setting only governs teammates' access, which an agent could not infer from the schema alone. No contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two front-loaded sentences express the primary action, the reverse action, and the permission model with no wasted words. The parenthetical clarifications ('share', 'creator only', 'also iterate on it') are slightly repetitive but each adds precision rather than padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers parameter semantics for the two enums and the resource type, which is the core of calling this tool correctly. It leaves gaps an agent would want for a non-idempotent mutation with no output schema: what the response looks like, who is authorized to publish, and what re-publishing (e.g., switching visibility or permission) does to existing shares.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full semantic burden, and it delivers on both enum parameters: it maps visibility values to their real-world meaning (private=creator only, team, organization) and defines permission (view vs edit, plus the org view-only override). artifactId is not elaborated, but its role as the dashboard identifier is obvious from the description and the uuid format in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific action pair — 'Publish (share)' and 'revert it to private' — applied to a named resource, the Duvo Pulse dashboard, with explicit scopes (team, organization, creator). This makes the tool's function clearly distinct from dashboard-lifecycle siblings like createPulseDashboard, updatePulseDashboard, and deletePulseDashboard, though it never names an alternative explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the trigger condition — an agent should call this when the goal is changing a dashboard's sharing scope — and it usefully covers the unshare case ('revert it to private'). However, it gives no explicit when-not-to-use guidance and does not name alternatives such as updatePulseDashboard for content changes or sendPulseDashboardMessage for targeted distribution, leaving tool selection to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

readAutomationDashboardDataRead Automation Dashboard DataA
Read-onlyIdempotent
Inspect

The figures a Module automation's Pulse dashboards show, computed server-side the same way the dashboard computes them: each tile's label, value, unit and display (the value as the dashboard prints it), with a description where the label alone leaves the figure unclear and a note for what the tile shows besides it. Call this for any number on a Module dashboard instead of reading the dashboard's HTML (getPulseDashboardHtml refuses Module dashboards for size) or paging through Cases: a recount can disagree with the tile the user sees. Pass dashboard_id for one dashboard, or leave it out for every dashboard of the automation the caller may open. range applies to dashboards with a time range control; the result names the range it read. Pass time_zone with the user's IANA zone so a day starts at their midnight, as their dashboard's do; without it days start at midnight UTC, and range.time_zone says which zone was used. Quote display, say the period it covers, and name and link the dashboard with its link. A dashboard whose figures are not declared, or that was changed since it was installed, comes back unsupported; one that could not be read comes back error; both carry a hint. Needs Queues on the team's plan. Each link is a path in the Duvo web app; give the user the full URL beside it (url).

NameRequiredDescriptionDefault
rangeNotoday, yesterday, week, month, ytd or all, for dashboards with a time range control; leave out for the range the dashboard opens on
time_zoneNoIANA zone the range's days start in, such as Europe/Prague. Pass the user's own zone so Today matches their dashboard; UTC when left out
dashboard_idNoOne of the automation's Module dashboards; leave out to read every one
automation_idYesAutomation ID

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/idempotent/non-destructive, and the description layers substantial extra context on top: the plan prerequisite ('Needs Queues on the team's plan'), the two failure modes with hints ('unsupported' for undeclared or changed dashboards, 'error' when unreadable), and the default time-zone behavior (UTC days unless time_zone is passed). That is well beyond the structured safety hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is a dense single block of roughly 180 words, but nearly every clause carries operational information (alternatives, failure states, defaults, presentation guidance). It is front-loaded with the resource, though the sheer density makes it harder to scan than a bulleted or shorter form.

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?

There is no output schema, so the description must describe returns — and it does: per-tile label/value/unit/display, optional description and note fields, the unsupported/error statuses with hints, the link path plus full url, and the range echo. Nothing an agent needs to call or present the result correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/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, but the description adds cross-parameter and result-linked meaning: omitting dashboard_id reads every dashboard, range only applies to dashboards with a time-range control, and the result echoes back which range and zone were used. It largely restates schema text but the range/zone echo adds genuine value.

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 opening states a specific verb and resource — the figures a Module automation's Pulse dashboards show — and immediately scopes it ('computed server-side the same way the dashboard computes them'). It explicitly distinguishes itself from siblings getPulseDashboardHtml and Case-paging, so an agent can route correctly without opening another schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a direct when-to-use rule ('Call this for any number on a Module dashboard') and names two alternatives with the reason to reject each (getPulseDashboardHtml refuses Module dashboards for size; recounting via Cases can disagree with the tile the user sees). This is explicit when/when-not/alternative guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

readAutomationPolicyRead Automation PolicyA
Read-onlyIdempotent
Inspect

Read an automation's whole Policy before answering anything about it: every question by section, with its id (the field id updateConfigField takes), key, type, answer and who gave it; counts.questions as the Policy screen's header counts them (required_open is what still blocks a run) apart from the module's pre-filled module_defaults; answers proposed by interviews and waiting for review; accepted and pending process-context notes; the interviews assigned; and pending_apply, the structural answers and notes not yet written into an Agent. running says whether the automation runs on live work: there a changed answer reaches its Agents from their next run, so name the question, its current answer and the new one, and change it only after the user says yes. A question whose bindings include structural changes how the Agents run; propose the matching Agent change too. Never invent an answer for a question shown as open. Give the user the full URLs in urls.

NameRequiredDescriptionDefault
automation_idYesAutomation ID
include_hiddenNoAlso list the questions a person hid, under hidden_fields. Defaults to false.

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/idempotent/non-destructive, and the description adds substantial context on top: the meaning of `running` (live work, answers reach Agents from their next run), the `structural` binding implication, the ban on inventing answers for open questions, and the instruction to surface full URLs. None of this is derivable from the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose well, but the body is one dense run-on with heavily chained clauses (counts, module_defaults, pending_apply, running, bindings) that is hard to scan. Every element is arguably relevant, yet it would benefit from being broken into shorter, structured sentences.

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?

There is no output schema, so the description carries the full burden of describing return values — and it does so field by field, including nested concepts like counts.questions, module_defaults, pending_apply and urls. An agent has everything needed to call it and interpret the result.

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 automation_id and include_hidden are already documented, and the enum on include_hidden is self-explanatory. The description explains the returned `id` field's link to updateConfigField but says nothing about the two input parameters beyond what the schema provides.

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?

States a specific verb and resource ('Read an automation's whole Policy') and then enumerates the return payload by name — questions by section, counts.questions, module_defaults, pending_apply, urls — which lets an agent distinguish it from getAutomation, getAutomationCurrent and readAutomationDashboardData without opening a schema.

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?

Gives a clear trigger ('before answering anything about it') and conditional rules for the running case ('change it only after the user says yes') plus the structural-bindings follow-up. It does not name an alternative sibling to use instead, so it stops short of full when/when-not routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

refreshPulseDashboardRefresh Pulse DashboardAInspect

Trigger an on-demand data refresh of a Duvo Pulse dashboard. The dashboard regenerates its connection-sourced values in the background — poll GET /artifacts/{artifactId} for status.

NameRequiredDescriptionDefault
artifactIdYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds meaningful behavioral detail beyond the annotations: the refresh is asynchronous, runs in the background, and requires polling GET /artifacts/{artifactId} for status. This aligns with readOnlyHint=false, idempotentHint=false, and destructiveHint=false, with no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise, front-loaded sentences convey the trigger action, the background behavior, and the follow-up polling step. Every sentence earns its place with no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter async mutation with no output schema, the description gives the essential workflow: trigger refresh, wait in background, poll for status. It could mention what the initial trigger response looks like or how long polling might take, but it is adequately complete for the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides only artifactId with UUID format and 0% schema description coverage. The description compensates by referencing artifactId in the polling URL, indicating the parameter identifies the artifact whose refresh status should be checked. Since there is only one parameter, this is sufficient.

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 states a specific action ('Trigger an on-demand data refresh'), a specific resource ('Duvo Pulse dashboard'), and the resulting behavior ('regenerates its connection-sourced values in the background'). This clearly distinguishes it from related siblings like updatePulseDashboard, createPulseDashboard, or refreshQueueAggregation.

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?

The description makes the use case clear: refresh the dashboard's connection-sourced data on demand, then monitor via polling. It does not explicitly discuss alternatives or when not to use it, but the context is specific enough that an agent can determine when this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

refreshQueueAggregationRefresh Queue AggregationBInspect

Force a fresh recompute of an aggregation definition.

NameRequiredDescriptionDefault
queue_idYesThe queue's unique identifier
definition_idYesThe aggregation definition's identifier

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish this is a mutating, non-idempotent operation, and the description adds the 'force fresh' semantics — implying it bypasses staleness checks and recomputes regardless of current state. However, it does not disclose whether the recompute is synchronous, whether it is expensive, what happens to the previously stored result, or what the response contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Seven words in a single sentence with the action verb 'Force' front-loaded. There is no filler, and every word contributes meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description should explain what a successful refresh returns, but does not. Combined with unresolved sibling ambiguity (evaluate vs refresh vs get result) and no mention of sync/async behavior or side effects on existing results, an agent is left guessing about the consequences of calling this tool.

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 both queue_id and definition_id are fully documented in the schema with identifiers and formats. The description adds no parameter-level meaning, which matches the baseline 3 since the schema carries the full burden.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Force a fresh recompute') and a specific resource ('aggregation definition'), making the core action unambiguous. However, it does not distinguish itself from siblings like evaluateQueueAggregation or getQueueAggregationResult, so an agent must infer the difference between refreshing, evaluating, and reading a result.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no guidance on when to use this tool versus siblings such as evaluateQueueAggregation, getQueueAggregationResult, or createQueueAggregation. There are no exclusions, no conditions, and no mention of preconditions (e.g., the definition must already exist), leaving selection entirely to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rejectAgentSuggestionReject Agent SuggestionC
Destructive
Inspect

Dismiss a pending suggestion.

NameRequiredDescriptionDefault
idYesThe suggestion's unique identifier

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, readOnlyHint=false, and openWorldHint=false, so the safety profile is covered. The description adds only the "pending" state constraint; it does not disclose what happens to the suggestion after rejection (deleted vs. marked rejected), or the effect of a repeated call given non-idempotency. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with zero filler and no redundancy. It is efficient, though the extreme brevity is part of why other dimensions are thin, so it is compact rather than fully earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with full schema coverage and rich annotations, the minimum needed to invoke it is present. Still, against a large family of suggestion tools (accept, consume, get, list), the description omits outcome and differentiation, so it is minimally sufficient rather than complete.

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%: the single id parameter is already documented as the suggestion's unique identifier with a UUID pattern. The description adds nothing about the parameter, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ("Dismiss") and resource ("a pending suggestion"), so the core action is understandable. However, it does not distinguish this tool from close siblings such as consumeAgentSuggestion, getAgentSuggestion, or the dismissClarity* variants, leaving the agent to infer which suggestion-related operation applies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word "pending" weakly implies the precondition that only actionable suggestions are rejected, but there is no explicit when-to-use statement, no when-not-to-use, and no mention of the alternative tools (consume, get, list). The agent receives no routing guidance among the many sibling suggestion tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

removeAutomationAgentRemove Automation AgentA
DestructiveIdempotent
Inspect

Remove an agent from an automation on a team that is on the Automations workspace, with or without revisions — membership is not versioned. Deleting the agent interrupts its active runs and pauses their sandboxes, exactly as a standalone agent delete does. On a team that changes its automations by revision, an agent the active revision binds is refused: activate a revision that omits it first.

NameRequiredDescriptionDefault
agent_idYesAgent ID
automation_idYesAutomation ID

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already mark this as destructive, non-read-only, idempotent, and closed-world. The description adds important behavioral context beyond annotations: deleting the agent interrupts active runs and pauses sandboxes, exactly like a standalone agent delete, and revision-bound agents are refused.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three tightly written sentences, front-loaded with the core action and scope, followed by side effects and the revision constraint. Every sentence adds distinct operational value without redundancy.

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 destructive mutation with no output schema and full parameter coverage in the schema, the description covers the essential invocation context: scope, side effects, and revision-binding restrictions. Nothing critical for correct invocation appears to be missing.

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 both required parameters (agent_id and automation_id) are already documented in the schema. The description does not add syntax or format details beyond what the schema provides, so the baseline of 3 is appropriate.

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 states a specific verb and resource ('Remove an agent from an automation') and scopes it to teams on the Automations workspace with or without revisions. It also distinguishes the operation from revision-bound membership changes by noting that membership is not versioned and that revision-bound agents are refused.

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 a clear when-not condition: if the active revision binds the agent, removal is refused and the caller must first activate a revision that omits it. It does not explicitly name sibling alternatives like removeAutomationRevisionAgent, but the revision constraint provides strong routing context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

removeAutomationQueueRemove Automation QueueA
DestructiveIdempotent
Inspect

Remove a queue from an automation, deleting the queue. Its cases are cleared and the runs working them interrupted, exactly as a standalone queue delete does. Queue membership is not versioned, so this behaves the same whether or not the team changes its automations by revision.

NameRequiredDescriptionDefault
automation_idYesAutomation ID
case_queue_idYesQueue ID

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and idempotentHint=true, but the description earns its keep by spelling out the blast radius: cases are cleared and in-flight runs are interrupted. It also explains the versioning behavior, which no annotation conveys.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the action and its destructive consequence. The versioning sentence is slightly repetitive ('behaves the same whether or not... by revision') but each sentence carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter destructive mutation with no output schema and full schema coverage, the description supplies the consequential detail an agent needs: what is destroyed, what happens to running work, and how it interacts with revisions. Only the explicit sibling routing is missing.

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% and both parameters (automation_id, case_queue_id) carry descriptions in the schema. The description adds no format or constraint detail beyond what the schema already provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Remove a queue from an automation, deleting the queue') and further pins down the semantics by equating it with a standalone queue delete. It implicitly distinguishes itself from the revision-scoped sibling by noting membership is not versioned, though it never names that sibling outright.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The revision sentence hints at when this tool is the right choice versus a revision-scoped removal, but it never explicitly says 'use X instead when Y'. No prerequisites or exclusions are stated, so the agent must infer the routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

removeClarityLandscapeNodePersonRemove Clarity Landscape Node PersonB
DestructiveIdempotent
Inspect

Remove a person from the process behind a process landscape node, and revoke the process access they were granted when they were added.

NameRequiredDescriptionDefault
orgIdYes
nodeIdYesA process landscape node that is linked to a real process.
teamIdNo
personIdYesThe person entry to change, as returned by listClarityLandscapeNodePeople.
pendingOnlyNoPass 'true' to cancel a pending invitation only. If the person has already accepted, nothing is removed and the request fails with 409.

TDQS

B3.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds real behavioral value by disclosing the side effect beyond the schema: the person's granted process access is revoked, not just unlinked.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence that names the action and its consequence with zero waste. Nothing padding, nothing missing structurally.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation with no output schema and partial parameter coverage, the description covers the main effect but omits when-to-use, the pendingOnly invitation-cancel path, and any permission requirements. Adequate but with clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description contributes nothing about any of the 5 parameters, and schema coverage is only 60% (orgId and teamId are undocumented in both places). With no parameter detail in the description, the coverage gap is not compensated.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource (remove a person from the process behind a landscape node) and adds the side effect (revoking process access). It is distinguishable from addClarityLandscapeNodePerson and updateClarityLandscapeNodePerson by the verb, though it does not name any sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus the closely related updateClarityLandscapeNodePerson (changing a person's role) or removeClarityProcessMember, nor any prerequisites or exclusions. Usage is only inferable from the verb.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

removeClarityProcessMemberRemove Clarity Process MemberA
DestructiveIdempotent
Inspect

Remove accepted access to a clarity process

NameRequiredDescriptionDefault
idYesClarity process ID.
invitationIdYesAccepted process invitation to remove.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate this is destructive and non-read-only. The description adds the useful context that it removes accepted access rather than merely deleting an invitation, but it does not describe side effects, irreversibility, or any post-removal behavior beyond what destructiveHint already implies.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no filler. It communicates the core action and target resource efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter destructive mutation whose safety profile is covered by annotations and whose parameters are fully documented, the description is sufficient. It could more explicitly state that it removes a member from the process, but no critical call-blocking context is missing.

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%, and both parameters are clearly documented in the schema. The tool description adds no additional meaning beyond what 'id' and 'invitationId' already convey.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action ('Remove') and a specific resource ('accepted access to a clarity process'), so an agent can distinguish it from tools like deleteClarityProcess or deleteClarityProcessInviteLink. However, it relies on the title for the 'member' concept and does not explicitly differentiate itself from sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'accepted' implies this tool is for removing members who have already accepted access, rather than pending invitations or invite links. No alternative tool is named and no explicit when-to-use or when-not-to-use guidance is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

removeConfigSectionRemove Config SectionA
DestructiveIdempotent
Inspect

Remove a section a person added to this automation's Policy, once it holds no question, hidden ones included. A section with questions, or one from the module template, is refused with a 409. Returns the removed section.

NameRequiredDescriptionDefault
section_keyYesThe section's key within the automation, such as 'about-you'
automation_idYesThe automation's unique identifier

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only supply the destructive/idempotent/openWorld profile; the description adds the failure mode (409), the precondition that even hidden questions block removal, the restriction to user-added sections, and the return value. Those are real behavioral facts an agent cannot get from the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, zero filler, front-loaded with the action and its precondition before the error case and return value. Every sentence contributes a distinct fact.

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 destructive mutation with no output schema, the description covers preconditions, refusal behavior, and the returned payload, and the annotations cover safety. Nothing an agent needs before invoking it is missing.

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 coverage is 100% and both parameters are fully documented in the schema (including a format example for section_key), so the description adds no additional parameter meaning. Baseline 3 applies when the schema carries the load.

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?

States a precise verb and resource ('Remove a section ... to this automation's Policy') and narrows scope to sections 'a person added', which separates it from addConfigSection/renameConfigSection/listConfigSections in the sibling set. An agent can identify the target object and its provenance without opening the schema.

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?

Gives an explicit precondition ('once it holds no question, hidden ones included') and the exact refusal conditions (questions present, or module-template section → 409). It does not name an alternative tool or a cleanup path for refused cases, but the when/when-not guidance is unusually concrete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

removeRevisionIntegrationRemove Revision IntegrationA
DestructiveIdempotent
Inspect

Remove an integration from an agent revision. Removes the slot for everyone on the revision, including all per-user connection pins. Requires edit permission on the agent.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID
integration_idYesIntegration ID (catalog integration ID or slot ID from the list response)
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds behavioral details beyond the annotations: it explains the removal affects the slot for everyone on the revision and covers all per-user connection pins. It also notes the edit permission requirement. While it does not enumerate error conditions or exact side effects, the annotations already flag destructive and idempotent nature, and the description provides additional scope context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise—two sentences—and directly states the action, scope, and a prerequisite. It is well-structured and free of unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool definition is complete for its purpose: it explains what it does, its effects, and required permissions. The absence of an output schema is acceptable given the destructive nature. It could mention potential error cases or relationship to unpin operations, but the provided information is sufficient for correct invocation in most contexts.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema includes descriptions for all parameters, with integration_id and selected_automation_revision_id having detailed explanations (catalog/slot ID, branching behavior). agent_id and build_id are self-explanatory. The main description does not add parameter-specific meaning, but the schema coverage is good, so overall clarity is high.

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 clearly states the tool removes an integration from an agent revision, and explicitly mentions it removes the slot for everyone on the revision including per-user connection pins. This distinguishes it from sibling tools like attachRevisionIntegrations or listRevisionIntegrations.

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?

The description indicates the action (removing an integration) and the requirement for edit permission, which implies when it should be used. It does not explicitly contrast with similar functions like unpinRevisionIntegrationConnection, but the 'including all per-user connection pins' phrase differentiates the scope, so usage is reasonably clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

removeTeamMemberRemove Team MemberA
DestructiveIdempotent
Inspect

Remove a member from a team. Removing another member requires the Superadmin role or above; any member may remove themselves (leaving the team). The last remaining Owner cannot be removed, and a member whose Owner role is inherited from the organization can only leave voluntarily.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
memberIdYesMember (user) ID

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag the tool as destructive and idempotent, but the description goes beyond them by disclosing role hierarchy requirements, self-removal behavior, and Owner protections. This is valuable behavioral context for a destructive membership operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core action and followed only by nontrivial constraints. No filler, no restating of schema fields, and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive membership operation, the description covers authorization, self-removal, and Owner edge cases. Combined with the rich team_id schema and annotations, an agent has enough context to invoke it correctly; the only minor gap is explicit output/error behavior, which is not essential for a remove operation.

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%, including detailed semantics for team_id and memberId, so the schema already carries the parameter documentation burden. The description adds no additional parameter-specific meaning beyond what the schema provides, so the baseline score applies.

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?

Description states a specific verb ('remove') and resource ('a member from a team'). It is immediately distinguishable from sibling tools like removeClarityProcessMember or removeClarityLandscapeNodePerson, leaving no ambiguity about what operation is performed.

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?

Provides clear contextual rules: removing another member requires Superadmin or above, any member may remove themselves, the last remaining Owner cannot be removed, and inherited-Owner members can only leave voluntarily. These act as preconditions and edge-case exclusions, though it stops short of explicitly naming alternative tools such as updateTeamMemberRole.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

renameConfigSectionRename Config SectionA
Destructive
Inspect

Rename a section of this automation's Policy. Its key and its questions stay as they are, and every reader shows the new name. A name another section has, ignoring case, is refused with a 409; the current name changes nothing. A module template reinstall keeps the rename.

NameRequiredDescriptionDefault
nameYesThe new heading; the section's key and its questions stay as they are
section_keyYesThe section's key within the automation, such as 'about-you'
automation_idYesThe automation's unique identifier

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare this is a non-read-only, destructive write (destructiveHint=true), and the description adds real context beyond them: the section key and questions survive, duplicate names (case-insensitive) are rejected with a 409, and the rename persists across module template reinstalls. That conflict code and persistence rule are exactly the kind of behavior annotations cannot express. Missing are authorization requirements and failure modes for an unknown section_key.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then dense, useful constraints — the 409 rule, the same-name no-op, and reinstall persistence all carry information. Slightly cryptic phrasing ('every reader shows the new name') costs a point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter mutation with safety behavior already covered by annotations and no output schema, the description supplies the important extras: conflict handling, no-op semantics, and durability across reinstalls. It stops short of covering missing-section errors or permission requirements, but is otherwise sufficient to call correctly.

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 all three parameters are already documented in the schema, making 3 the baseline. The description's note that the key and questions stay as they are restates and slightly reinforces the section_key semantics, but adds no format, range, or lookup detail the schema lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb+resource: 'Rename a section of this automation's Policy.' The scope of what is and is not changed (key and questions untouched) is clear. It does not explicitly distinguish itself from near siblings such as removeConfigSection, reorderConfigSections, or addConfigSection, but the verb is inherently unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: the tool is for renaming an existing section whose key is known. There is no explicit 'use this instead of X' routing and no statement of prerequisites (e.g., needing write access to the automation, or that the section must exist). Guidance exists but must be inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

renameFileRename FileC
Destructive
Inspect

Rename a file in team storage.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
relativePathYesCurrent path of the file relative to the team's storage root
newFilenameOnlyYesNew file name (no extension; the existing extension is preserved)

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false and readOnlyHint=false, so the safety profile is covered structurally. The description adds nothing beyond that: it does not say whether existing links/references break, whether the extension is preserved, or what the response contains, which is the kind of extra context that would earn credit here.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no padding or redundancy; the purpose is front-loaded. It is efficient, though the extreme brevity borders on under-specification rather than crisp conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is low-complexity (3 flat params, no output schema, no nested objects) and the schema plus annotations carry most of the burden, so the description is minimally viable. It still omits any note about the destructive nature of renaming (broken references, permissions), which would be useful for an agent deciding whether to call it.

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 all three parameters (team_id, relativePath, newFilenameOnly) are already fully documented in the schema, including the extension-preservation rule and the API-key vs OAuth team semantics. The description adds no parameter meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (Rename) and resource (a file in team storage), so an agent immediately knows the operation. It does not, however, differentiate itself from neighboring file-mutation tools such as updateFileContent or deleteFile, nor does it clarify the scope beyond 'team storage'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no statement of prerequisites, and no mention of alternatives (e.g., updateFileContent vs. renameFile). The agent must infer usage entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reorderClarityFoldersReorder Clarity FoldersA
Destructive
Inspect

Reorder the team's process folders to match the given id order. The payload must name every folder exactly once.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
folderIdsYesEvery team folder ID, in the desired display order.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructive=true, readOnly=false, idempotent=false, and openWorld=false, so the safety profile is covered. The description adds the important constraint that the payload must name every folder exactly once, but does not explain side effects, permissions, or failure behavior, meriting a 3.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action, with no redundant or filler text. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with complete schema coverage, annotations covering safety, and no output schema, the description supplies the core operation and the exhaustive-payload constraint. It omits when-to-use and side-effect detail, but the structured fields cover the rest, so it is mostly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the schema fully describes both team_id and folderIds. The description adds the 'exactly once' uniqueness requirement, which is not expressed by the array schema (no uniqueItems), so it adds value beyond the schema and earns a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Reorder') and resource ('the team's process folders') and specifies the ordering basis ('match the given id order'). It does not name sibling tools like reorderClarityLandscapeAreas or reorderConfigSections, so sibling differentiation is implicit rather than explicit, fitting a 4.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no alternatives, and no prerequisites. The description states the operation and its payload constraint but does not tell an agent when to choose this over list/update/move folder operations, so it scores 2.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reorderClarityLandscapeAreasReorder Clarity Landscape AreasA
DestructiveIdempotent
Inspect

Reorder a sibling group of the organization's process landscape area folders left-to-right — the top-level areas by default, or the folder children of parentId (organization admin+). This changes display order only; use setClarityLandscapeNodePlacement to move a node to a different parent.

NameRequiredDescriptionDefault
orgIdYes
parentIdNoThe parent area whose folder children are being reordered. Omit or pass null to reorder the top-level areas.
orderedAreaIdsYesEvery area folder in the sibling group, exactly once, in the order you want them displayed left-to-right. Read the current siblings first (getClarityProcessTree); a partial list is rejected with 400.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide idempotentHint=true, destructiveHint=true, and readOnlyHint=false, so the mutation profile is partly covered. The description adds real value beyond them: the admin+ authorization requirement and the reassurance that this 'changes display order only' (reorder vs. reparent). There is a mild tension in that annotations mark it destructive while the description says only display order changes, but that reads as ordering being overwritten rather than an outright contradiction; the description could be more explicit about whether the full sibling set is replaced.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences that are tightly front-loaded: the action and its scope come first, followed immediately by the routing alternative. No filler, and the parentId default is explained inline efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 3-parameter reorder mutation with no output schema, the definition gives the agent what it needs: scope, permission, safety profile (via annotations plus 'display order only'), and the sibling alternative. The one thin spot is the ordering-replacement semantics and the required complete-list precondition, which is only carried by the schema rather than reinforced in the description.

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 67%, and the schema already documents parentId ('Omit or pass null to reorder the top-level areas') and the orderedAreaIds all-siblings-exactly-once rule with the 400 consequence. The description largely restates the parentId behavior ('top-level areas by default, or the folder children of parentId') rather than adding new syntax or constraints, so it lands at the baseline for a partially covered schema.

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 names a specific verb ('Reorder'), a specific resource ('sibling group of the organization's process landscape area folders'), and the exact scope ('left-to-right', 'top-level areas by default, or the folder children of parentId'). It also names the sibling tool it is not (setClarityLandscapeNodePlacement) for reparenting, so an agent can distinguish it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit usage context: default top-level reordering vs. scoping to children of parentId. It states the exclusion clearly ('use setClarityLandscapeNodePlacement to move a node to a different parent'), and the required permission level ('organization admin+') is disclosed. This is exactly the when/when-not/alternative guidance the dimension asks for.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reorderConfigSectionsReorder Config SectionsA
DestructiveIdempotent
Inspect

Replace the display order of this automation's Policy sections. keys must list every section key of the automation exactly once, else a 400 names what is missing, unknown or repeated. Returns every section in its new order. A module template reinstall keeps the order of the sections moved here.

NameRequiredDescriptionDefault
keysYesEvery section key of the automation exactly once, in the new display order
automation_idYesThe automation's unique identifier

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds genuinely useful behavior beyond that: the 400 validation error naming missing/unknown/repeated keys, the return of every section in the new order, and the durability note that a module template reinstall preserves the moved order.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, each carrying distinct information: the action, the validation contract, the return, and the persistence caveat. Front-loaded with the core operation and no filler, though it is slightly dense with three separate facts packed in.

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?

With no output schema, the description steps in to describe the return value ('every section in its new order'), plus the validation-failure behavior and the reinstall persistence edge case. Nothing an agent needs to invoke this two-parameter mutation correctly is missing.

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 coverage is 100%, and the schema itself already documents both keys and automation_id, including the 'every section key exactly once' constraint. The description largely restates that constraint and adds only the error response detail, so the baseline of 3 is appropriate.

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?

States a specific verb (replace/reorder the display order) and resource (this automation's Policy sections), which cleanly separates it from siblings like renameConfigSection, addConfigSection and removeConfigSection. An agent can identify the operation without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description conveys a key usage constraint (keys must list every section key exactly once) but never states when to choose this tool versus renameConfigSection or listConfigSections, nor any prerequisites such as reading the current order first. Usage is implied rather than guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

replaceCaseQueueEvalRubricsReplace Case Queue Eval RubricsA
Destructive
Inspect

Replace the entire case-level evaluation rubric set on a queue's current version (1 to N rubrics, N being 12 by default and 25 on teams with the newer rubric generator enabled). Existing rubrics are removed and the supplied list becomes the new set. An empty list is refused — whole-case evaluation regenerates rubrics for an empty set at the next settlement, so a cleared set would not stay cleared; remove individual rubrics instead. Targets the queue's current version (build-set), which exists once its first Agent-processed case settles — this fails with 409 before then. Cases already judged keep their original verdicts.

NameRequiredDescriptionDefault
rubricsYesThe complete case-level rubric set for the queue's current version (at least 1 rubric). Replaces every existing rubric.
queue_idYesThe queue's unique identifier

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true, readOnlyHint=false and idempotentHint=false, but the description adds what the annotations cannot: existing rubrics are removed and replaced, why an empty list is rejected (regeneration at settlement), and that already-judged cases keep their verdicts. This is rich, non-duplicative behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then the destructive consequence, then the empty-list caveat, then the version precondition. Every sentence carries a distinct piece of operational information; none is filler.

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 destructive mutation tool with no output schema, the description covers the mutation semantics, failure modes (409, empty-list refusal), limits, and side effects on already-judged cases. Nothing an agent needs to call it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters are documented in the schema, so much of the value is already structured. The description nevertheless adds meaning beyond the schema: the effective rubric count range (1 to 12 by default, 25 with the newer generator) and the semantics of 'empty list' for the rubrics array.

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?

States a specific verb and resource: replacing the entire case-level rubric set on a queue's current version. The scope ('entire set', 'current version / build-set') clearly separates it from the sibling create/update/delete single-rubric tools and from replaceEvalRubrics at the non-case level.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives the when-to-use (whole-set replacement), an explicit when-not with an alternative action ('An empty list is refused... remove individual rubrics instead'), and a precondition for use ('fails with 409 before its first Agent-processed case settles'). Routing is fully inferable without opening another schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

replaceEvalRubricsReplace Eval RubricsA
Destructive
Inspect

Replace a build's entire Agent-specific evaluation rubric set in one call (at most 5 rubrics by default, 25 on teams with the newer rubric generator enabled). Existing custom rubrics are removed and the supplied list becomes the new set; pass an empty array to clear them. Defaults to the Agent's live build; pass build_id to target a specific revision.

NameRequiredDescriptionDefault
agentIdYesThe agent's unique identifier (Assignment ID)
rubricsYesThe complete custom rubric set for the build. Replaces every existing custom rubric; pass an empty array to clear them.
build_idNoReplace the custom rubrics on this build (revision). Defaults to the agent's live build when omitted.
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and non-idempotent, so safety is covered. The description adds real behavioral context beyond that: existing custom rubrics are removed and fully replaced, a default cap of 5 rubrics (25 with the newer generator), and the empty-array clearing behavior. It omits permission/auth requirements, but the destruction semantics are unusually well disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, front-loaded with the core replace action and limits; every clause carries information (caps, clearing, default target). The opening sentence is long but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent mutation with no output schema, the description covers scope, replacement semantics, cardinality limits, and the target-build default. The remaining gap is failure/permission behavior, which is minor given annotations already declare the destructive profile.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/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, but the description contributes meaning not in the schema: the default cap of 5 rubrics (schema only shows maxItems 25) and the explicit note that build_id targets a specific revision versus the live build default. That extra constraint raises it above baseline.

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?

States a specific verb (Replace) and resource (a build's entire Agent-specific evaluation rubric set), and scopes it clearly to the build level, which separates it from siblings like replaceCaseQueueEvalRubrics, createEvalRubric, and updateEvalRubric. An agent can identify the operation and its replace-semantics without opening the schema.

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?

Gives concrete conditions: defaults to the Agent's live build unless build_id is passed, and an empty array clears the set. However, it never explicitly routes the agent away from the singular siblings (createEvalRubric / updateEvalRubric / deleteEvalRubric) when only one rubric changes, so the when-not guidance is inferred rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

replaceRevisionIntegrationQueuesReplace Revision Integration QueuesA
DestructiveIdempotent
Inspect

Replace the set of queues linked to this build's case-queue integration slot. Send the full desired queue list — any queues not in the list will be unlinked. Requires edit permission on the agent. After linking, call getRevisionCaseQueueSetup to confirm the slot now reports linked_queue_count > 0.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID
queue_idsYesFull set of queue IDs to link to this slot. Replaces any existing links.
integration_idYesIntegration ID
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, but the description adds what gets destroyed ('any queues not in the list will be unlinked'), the authorization requirement (edit permission on the agent), and a concrete post-call verification step — context that annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the destructive replace semantic, then permission, then verification. Every sentence carries distinct operational value with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation with no output schema, the description covers semantics, prerequisites, and a verification path, which is nearly sufficient. It does not state what the call itself returns or how failures surface, a minor gap given there is no output schema to lean on.

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 all five parameters, including the nuanced selected_automation_revision_id branching behavior, are already documented in the schema. The description restates the queue_ids replace semantics but adds no syntax or format detail beyond it; baseline 3 is appropriate.

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?

States a specific verb (Replace) and resource (the set of queues linked to this build's case-queue integration slot), and the replace-vs-add semantics immediately distinguish it from sibling tools like addAutomationQueue and listRevisionIntegrationQueues. An agent can identify the operation without opening the schema.

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?

Gives clear conditions for use (send the full desired list, unlisted queues are unlinked), a prerequisite (edit permission on the agent), and a follow-up verification call to getRevisionCaseQueueSetup. It does not name an explicit alternative (e.g. an add/remove-single-queue tool), so it stops short of full when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

respondToHumanRequestRespond To Human RequestAInspect

Respond to a human-in-the-loop request. Use 'approved' (true/false) for approval-type requests, or 'answers' ({question: answer}) for question-type requests. Only works when the run is in 'waiting' status.

NameRequiredDescriptionDefault
run_idYesThe run's unique identifier
answersNoFor question-type requests: a map of question text to answer. Multi-select answers should be comma-separated. Each answer is at most 10240 UTF-8 bytes.
approvedNoFor approval-type requests: true to approve, false to deny
request_idYesThe human request's unique identifier

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare a non-readOnly, non-destructive, non-idempotent, open-world mutation. The description adds genuine behavioral context beyond this: the run must be in 'waiting' status for the call to work, which is a critical state precondition not expressed in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with the core purpose front-loaded, followed by the parameter-selection rule and the state precondition. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no output schema, the description covers the two request modes and the waiting-status precondition. It doesn't state what happens after responding (e.g., run resumption) or error behavior if the precondition is unmet, but it is largely complete for correct invocation.

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 coverage is 100% and the schema descriptions already explain approved ('true to approve, false to deny') and answers ('map of question text to answer'). The description's parameter guidance largely restates this, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Respond to a human-in-the-loop request'), which is far more distinctive than most siblings like answerPulseDashboardQuestion or postRunMessage. It's clear what the tool does, though it doesn't explicitly distinguish itself from sibling response/message tools.

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?

Gives explicit conditional guidance: use 'approved' for approval-type requests, 'answers' for question-type requests, and notes the 'waiting' status precondition. It doesn't name an alternative tool to use when the run is not waiting, but the selection logic between request types is well covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

restoreConfigFieldRestore Config FieldB
Destructive
Inspect

Show a hidden Policy question again, with the answer it had.

NameRequiredDescriptionDefault
field_idYesThe config field's unique identifier
automation_idYesThe automation's unique identifier

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=false, so the safety profile is covered. The description adds the useful fact that the prior answer is restored, but it never explains what happens to the current answer or why the operation is flagged destructive, leaving the key behavioral consequence implicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no padding and the key action front-loaded. It is efficient, though the 'Policy question' phrasing introduces a terminology mismatch with the tool name that costs a little clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations carrying the safety profile, a fully documented two-parameter schema, and no output schema, the minimum is met. Still, for a destructive restore operation the description should say what the restore overwrites and how it relates to updateConfigField/hideConfigField.

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% and both UUID parameters are documented in the schema, so the baseline is 3. The description adds no format, constraint, or relationship detail beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a concrete action ('Show a hidden Policy question again') on a specific resource, and the restoration of the prior answer is a meaningful detail. However, it uses 'Policy question' rather than the tool's own 'Config Field' vocabulary and never distinguishes itself from siblings like hideConfigField, addConfigField, or updateConfigField.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use statement and no mention of alternatives. An agent can infer it is the inverse of hideConfigField, but nothing in the text confirms that or states any prerequisite (e.g., that the field must currently be hidden).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

restorePulseDashboardVersionRestore Pulse Dashboard VersionB
Destructive
Inspect

Restore a previous version of a Duvo Pulse dashboard, making it live again (requires edit access). Non-destructive — it moves the head pointer to the chosen version.

NameRequiredDescriptionDefault
artifactIdYes
revisionIdYes

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=true, and the description does add real context: the edit-access requirement and the 'moves the head pointer' mechanism. However, it explicitly labels the operation 'Non-destructive', which directly opposes destructiveHint=true, so the framing is misleading rather than clarifying.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence front-loads the action and outcome before the parenthetical prerequisite and the mechanism clause. No filler or repetition; every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter mutation tool with no output schema and full annotation coverage, the description covers purpose, access requirement, and mechanism, which is adequate. The main gap is that it leaves both parameters semantically undocumented and its safety framing conflicts with the annotation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for both parameters. The description only alludes to 'the chosen version', loosely implying revisionId, and says nothing about artifactId, its UUID format, or how to obtain either value. With two undocumented params, the description fails to compensate for the schema gap.

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 states a specific verb (Restore), resource (a previous version of a Duvo Pulse dashboard), and outcome (making it live again). It is easy to distinguish from siblings such as listPulseDashboardVersions or getPulseDashboardVersionHtml, which read rather than activate a version.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a prerequisite (requires edit access) and implies the usage context (rolling a dashboard back to an earlier revision), but names no explicit alternatives or when-not-to-use conditions. Nothing tells the agent when to prefer this over updatePulseDashboard or refreshPulseDashboard.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resumeBuilderRunResume Builder RunAInspect

Resume a builder run that is waiting for user input

NameRequiredDescriptionDefault
answersYesAnswers keyed by the exact question text in pending_user_questions.questions.
builder_run_idYesThe builder run waiting for answers.

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds little beyond the annotations: it restates the title and the waiting-state condition. It does not mention what happens after resuming, whether answers replace or supplement existing data, or any other behavioral consequences. Annotations already convey that it is non-read-only, non-destructive, and non-idempotent, so the description carries nearly no extra weight.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is one concise sentence achieving both purpose and usage clarity without superfluous words. It is front-loaded and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With two fully-schema'd parameters and no output schema, the description supplies the core use case but omits any notion of what the agent should expect after a successful resume (e.g., no longer waiting, next pending step, or a confirmation response). A brief note about the outcome or state change would round out the definition.

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?

The input schema thoroughly describes both parameters (builder_run_id and answers, 100% coverage). The tool description adds no parameter-specific information. With high schema coverage, the baseline of 3 is appropriate.

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 uses a specific verb 'Resume' and a specific resource 'a builder run', qualified by the state 'waiting for user input'. This clearly differentiates it from siblings such as startRun, cancelBuilderRun, and getBuilderRun.

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?

The phrase 'that is waiting for user input' provides a clear condition for when the tool should be used, distinguishing it from runs in other states. It doesn't explicitly name alternatives or exclusions, so it falls short of a perfect score.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

revertClarityProcessSnapshotRevert Clarity Process SnapshotA
DestructiveIdempotent
Inspect

Archive a Clarity v2 snapshot of either kind. If the live row is archived, the repository auto-promotes the latest historic row of the same kind.

NameRequiredDescriptionDefault
kindYesSnapshot kind to list
process_idYesThe clarity process id
snapshot_idYesSnapshot id

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the operation as destructive and idempotent, so the description adds value by specifying the concrete state change: archiving a snapshot, and if it is the live row, auto-promoting the latest historic row of the same kind. This goes beyond the generic destructive hint, though it stops short of describing return behavior or the non-live-row case.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no filler. The primary action is front-loaded, and the second sentence earns its place by explaining the important automatic promotion behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter destructive operation, the description plus annotations and full schema coverage cover the essential state transition. The remaining gaps are minor: there is no output schema and no explicit statement about what happens when a non-live snapshot is archived, but the core behavior is clear enough for an agent to invoke the tool correctly.

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 applies. The phrase 'either kind' loosely maps to the kind enum and the live/historic distinction adds context around snapshot_id, but the description does not provide parameter-specific detail beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a concrete verb and object: 'Archive a Clarity v2 snapshot of either kind,' and it explains the key side effect (auto-promotion of the latest historic row). It is clear about what the tool does, though it does not explicitly distinguish itself from closely related snapshot operations such as promoteClarityProcessSnapshot or saveClarityProcessSnapshot.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is given about when to call this tool versus any of the many sibling snapshot tools. The conditional sentence describes a behavior that occurs if the live row is archived, but it does not state the intended trigger, prerequisites, or when an alternative like promote or save would be more appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

saveClarityProcessSnapshotSave Clarity Process SnapshotCInspect

Save user edits as the live Clarity v2 snapshot for the selected kind.

NameRequiredDescriptionDefault
kindYesSnapshot kind to list
swotNoSWOT analysis produced by the swot-analysis postprocessing agent. `undefined` = agent has not yet run; `null` = agent ran and produced no analysis.
lanesNoRole lanes of the process map, each defined once. Absent on snapshots written before lanes existed; the read model derives them from each step's role.
stepsYes
summaryNoOne short paragraph (3-5 sentences) describing the captured process at a glance. Surfaced at the top of the current-process tab so reviewers can orient themselves before scanning the steps. Example: "Customers order beer at the bar; the bartender greets them, picks an option matching their preference, pours and garnishes the glass, then rings the order through the POS before serving."
process_idYesThe clarity process id
projectedImpactNoAnswer-first, MECE-structured business case. 4-8 sentences of prose + one markdown assumptions table. Null when team context is insufficient to produce any quantitative or qualitative assessment.
baselineSnapshotIdYes
clarityCurrentProcessIdNo

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=false, and idempotentHint=false, so the safety profile is covered. The description adds real context by saying it writes the 'live' snapshot from 'user edits', implying it replaces the current live version, but it says nothing about what baselineSnapshotId governs, retry/idempotency behavior, or authorization requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted words; the verb and resource lead. It is efficient, though arguably under-sized for a 9-parameter mutation rather than genuinely concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex mutation with a very large nested steps schema, no output schema, and a required baselineSnapshotId, one sentence is not enough. The description omits what 'live' replaces, how the baseline is used, and what happens to existing snapshot state, so an agent lacks the context needed to call it confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 9 parameters and 67% schema description coverage, the description should help close the gap but instead adds nothing about any parameter. It gestures at 'kind' and 'user edits' but does not explain baselineSnapshotId, clarityCurrentProcessId, or the summary/projectedImpact fields, leaving meaning to the schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (Save) and resource (Clarity v2 snapshot) with a scope qualifier (live, for the selected kind). An agent can distinguish this write path from generate/promote/revert siblings, but 'the selected kind' is left to the enum and the description never names any sibling tool explicitly, so differentiation is partial.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus generateClarityProcessSnapshot, promoteClarityProcessSnapshot, or revertClarityProcessSnapshot, no prerequisites, and no exclusions. 'Save user edits' implies an edit-mode context but leaves the agent to infer it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

searchCasesSearch CasesAInspect

Search cases in a queue with rich filters (multi-status, date ranges, label-based filters, and field-value filters over a typed queue's json_data). Use this when the simple query-string filters on GET /v2/queues/:queue_id/cases aren't enough. Each json_data entry is {path, operator, value} where path is a declared scalar in JSONPath dotted form ($.invoice.amount); entries are ANDed, so two comparisons on one path express a range. A path the queue's Case schema does not declare is rejected rather than ignored, as is a value that does not match the field's declared type. The contains operator is case-sensitive (unlike the free-text search parameter). Set count_only=true to skip Case row selection, enrichment, and transformation. The normal response shape is returned with cases: [] and the matching total.

NameRequiredDescriptionDefault
limitNo
offsetNo
searchNo
filtersNo
sort_byNocreated_at
queue_idYesThe queue's unique identifier
count_onlyNoSkip Case row selection, enrichment, and transformation. The normal response shape contains an empty cases array and the matching total.
sort_orderNodesc

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing validation behavior (undeclared paths and type-mismatched values are rejected, not ignored), AND semantics across json_data entries, case-sensitivity of `contains`, and the side effects of count_only on selection/enrichment/transformation. It omits pagination limits and auth requirements, and there is mild tension between 'search' and readOnlyHint=false, though this is a POST-style search endpoint rather than an actual write.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the routing condition are front-loaded, and each subsequent sentence carries distinct information (json_data shape, validation, contains semantics, count_only). It is dense but not padded, though it runs long enough that a reader must hold several rules at once.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, and the description partially compensates by stating that count_only returns the normal shape with cases: [] and the matching total. The content of a normal (non-count) response is left implicit, and limit/offset pagination is left entirely to the schema, leaving a modest gap for a search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 25% schema description coverage, the description carries real weight: it explains the {path, operator, value} shape of json_data, the JSONPath dotted path format, ANDing across entries, and the count_only flag's effect on the response. It adds little about labels, status, priority, the date-range filters, or sort_by/sort_order beyond what the schema already implies.

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?

States a specific verb and resource with scope ('Search cases in a queue with rich filters') and immediately contrasts it with the simpler query-string filter endpoint, so an agent can tell it apart from listCases without opening either schema.

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?

Gives a clear selection condition: 'Use this when the simple query-string filters ... aren't enough,' which routes the agent away from the basic list endpoint. It does not name the sibling tool explicitly or state when-not to use this tool (e.g. bulk export), so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sendClarityInterviewInvitesSend Clarity Interview InvitesAInspect

Invite people to record an interview about this Clarity process, and email each of them. To invite people from the organization chart or landscape, first use the Clarity hierarchy people tools to find their names and email addresses, then pass them as invitees. Set includeProcessPeople to true to also invite everyone already listed as a person on this process. At most 25 unique recipients per call. Each invitee gets a Clarity process invitation, exactly as the Invite dialog creates one; someone already invited is sent their invitation again rather than a second one. Where the team has account-free interview links on, people without a Duvo account get a link that opens the interview directly and expires after 30 days; everyone else gets the normal invitation that asks them to sign in. Revoke a pending invitation with deleteTeamInvite.

NameRequiredDescriptionDefault
idYesThe Clarity process ID.
messageNoOptional plain-text note added to each invitation email, at most 500 characters. Line breaks are collapsed and markup is shown as text.
inviteesNoPeople found through org-chart or landscape people tools. At most 25 unique recipients per call, counting includeProcessPeople.
includeProcessPeopleNoAlso invite every active process person with an email address. Use this for people already assigned to the process.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (not read-only, open-world, non-idempotent, non-destructive), and the description adds substantial behavioral detail on top: a 25-recipient cap, re-send semantics for already-invited people instead of creating duplicates, and the 30-day account-free interview link vs. the normal sign-in invitation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and organized so each sentence adds a distinct rule (invitee sourcing, cap, re-send behavior, link expiry, revocation). It is one dense paragraph, but nearly every clause earns its place; only slight compaction would improve it.

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?

With no output schema, the description still conveys the observable outcome (invitation created and emailed, link type depends on team settings, duplicate handling), which is what an agent needs to call it correctly and predict effects.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: the source of invitees (org-chart/landscape people tools), the interaction between invitees and includeProcessPeople in the 25-recipient cap, and revocation. It stops short of explaining the message field beyond what the schema already documents.

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?

States a specific verb and resource: inviting people to record an interview for a named Clarity process and emailing each invitee. It is clearly distinguishable from sibling invite tools (createTeamInvite, bulkCreateTeamInvites, inviteClarityMeetingNotetaker) because it is scoped to Clarity interview invitations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells the agent to first use the Clarity hierarchy people tools to resolve names/emails, describes when to set includeProcessPeople to true, and names deleteTeamInvite as the way to revoke a pending invitation. When-to-use and the alternative are both stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sendPulseDashboardMessageSend Pulse Dashboard MessageAInspect

Send an instruction to iterate on a Duvo Pulse dashboard (e.g. 'make it a bar chart', 'filter to last 14 days'). The creator can always iterate; teammates can too when the Pulse is published to the team with edit access. The agent regenerates asynchronously — poll GET /artifacts/{artifactId} for status.

NameRequiredDescriptionDefault
messageYes
artifactIdYes
attachmentsNoAttachments to hand the agent, uploaded beforehand via the upload-urls endpoint (max 5)
from_revision_idNo
selected_elementNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses that the tool triggers asynchronous regeneration and instructs polling the artifact status, which is key behavioral information not fully captured by annotations. It aligns with annotations (readOnlyHint false, destructiveHint false) and adds operational detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured, using three sentences to convey purpose, permissions, and async behavior. Minor awkwardness like 'Duvo Pulse' (possibly a typo) slightly detracts, but overall it is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core action and async polling, but given the complexity of five parameters and nested objects, it leaves out important context about attachments and revision handling. It does not describe the expected outcome or response format, though the polling URL partially compensates.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With only 20% schema description coverage, the description provides minimal help for parameters. It indirectly mentions the message and artifactId via examples and the polling URL, but attachments, from_revision_id, and nested objects are left unexplained, leaving the agent to guess.

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 clearly states that the tool sends an instruction to iterate on a Pulse dashboard, with concrete examples of such instructions. It distinguishes the tool's purpose from other dashboard-related actions, making it easy for an agent to understand when to use it.

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?

The description provides usage context by explaining who can iterate (creator always, teammates with edit access when published) and that the operation is asynchronous, requiring polling. It does not explicitly compare to alternative tools, but the conditions and workflow are sufficiently clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sendTeamInviteEmailSend Team Invite EmailAInspect

Email an invitation to its recipient. Use this to deliver an invitation created by createTeamInvite (which never sends mail on its own), or to resend one the recipient never received. The accept link is always built from the server-configured app origin.

NameRequiredDescriptionDefault
idYesID of the invitation to email.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
frontendUrlNoDeprecated. Accepted for backward compatibility and IGNORED: the accept link is always built from the server-configured app origin, so a caller cannot point invitation emails at another host.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations (readOnlyHint=false, destructiveHint=false), the description adds two useful behavioral facts: createTeamInvite has no mail side effect, and the accept link is always derived from the server-configured app origin, so frontendUrl cannot override it. It does not detail auth/rate limits or post-send state changes, but the primary side effect—sending an email—is explicit.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each with a distinct job: main action, when to use, and server-origin constraint. No filler or duplication of schema content. The most important information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-object send action with only three parameters and no output schema, the description covers what the tool does, when to use it, its relationship to createTeamInvite, and a key behavioral constraint. It does not specify return/error behavior or what happens if the invitation was already sent, but these are minor for a tool of this complexity.

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%, and the schema already explains id, team_id, and the deprecated ignored frontendUrl. The description reinforces the id semantics contextually and explains why frontendUrl is irrelevant, but it does not add substantial param-level meaning beyond the schema. Baseline 3 is appropriate.

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 'Email an invitation to its recipient,' naming a specific verb and object. It further distinguishes itself from createTeamInvite by stating that tool never sends mail on its own, and clarifies that this tool also handles resending. This is enough for an agent to differentiate it from siblings like listTeamInvites or bulkCreateTeamInvites.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs when to use: to deliver an invitation created by createTeamInvite or to resend one the recipient never received. It names createTeamInvite as the companion creation tool that does not send mail, providing an alternative and the condition that selects this tool. The guidance is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

setCaseJsonDataFieldsSet Case Json Data FieldsA
Destructive
Inspect

Set one or more fields of a typed case's structured json_data payload in one atomic write, leaving every other field as stored. Prefer this over PATCH /cases/{case_id} with a full json_data object when changing some fields: the write reads and locks the latest payload in the database, so a concurrent edit to another field, or to another item of the same array, is preserved. Each set entry names a path, a JSONPath declared in the queue's current Case schema, and the value to store there. A path is dotted object fields ($.invoice.amount) with optional array indices in brackets ($.lines[0] for a whole item, $.lines[0].amount for one field of it). An index must name an item that already exists; an out-of-range index or a non-array parent is refused, and a write never adds or removes items. A value can be any JSON value, including an object for an object field. Paths must be distinct, and no path may sit inside another in the same request ($.lines beside $.lines[0], or $.lines[0] beside $.lines[0].amount). An index names a position, so when the array can change between your read and your write, add expect entries that pin the item, such as its id field ($.lines[0].id): if any stored value differs, nothing is written and the response is a 409. The resulting payload is validated against the queue's current Case schema and the case is re-pinned to that schema version; if any entry is refused, nothing is written. A case without a structured payload yet must be given one with PATCH /cases/{case_id} first. Returns the updated case with its event history and approval batches.

NameRequiredDescriptionDefault
setYesThe fields to set, applied together (1 to 100).
expectNoPreconditions checked against the latest stored payload before any field is set (up to 100). If one does not match, nothing is written and the response is a 409. Use them to make sure an array index still names the item you read.
case_idYesThe case's unique identifier

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses read-and-lock semantics, atomicity ('if any entry is refused, nothing is written'), 409 on `expect` mismatch, out-of-range/non-array index refusal, no add/remove of array items, schema validation and case re-pinning, and the return shape (updated case with event history and approval batches). The destructiveHint annotation is consistent with the described overwrite behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The critical routing information (purpose, alternative, prerequisite) is front-loaded and almost every sentence carries substantive constraint detail. However it is a single dense paragraph of roughly 300 words, and the path/indices/`expect` rules could be split or tightened for scanability without losing meaning.

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 mutation tool with no output schema, the description covers all the gaps that matter: prerequisites, atomicity, error conditions (409, 400), index constraints, validation, and the return value. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, but the description adds meaning not in the schema: JSONPath syntax with dotted fields and bracket indices, the rule that indices must name existing items, that paths must be distinct, and that no path may nest inside another in the same request. It also explains the purpose of `expect` (pinning an array item by id before a concurrent-write-sensitive set).

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?

States a specific verb and resource ('Set one or more fields of a typed case's structured `json_data` payload in one atomic write') and immediately differentiates itself from the sibling write path (`PATCH /cases/{case_id}` with a full `json_data` object). An agent can distinguish this from `updateCase` without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternative (`PATCH /cases/{case_id}`) and the condition that selects this tool ('when changing some fields'), plus the prerequisite that a case with no structured payload must be initialized via PATCH first. It also states when to add `expect` entries (when the array can change between read and write). No usage inference is left to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

setClarityLandscapeNodePlacementSet Clarity Landscape Node PlacementB
DestructiveIdempotent
Inspect

Move a process landscape node (team builder or above for team processes; team manager or above for team proposals; organization admin for areas)

NameRequiredDescriptionDefault
orgIdYes
nodeIdYes
parentIdYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true, and readOnlyHint=false, so the safety profile is largely covered. The description adds a real behavioral fact not in the annotations: tiered permission requirements (team builder/team manager/org admin depending on node type). It does not, however, explain what 'move' changes beyond reparenting (e.g. effect on children, ordering, or downstream assignments).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with the action front-loaded and no filler. The trailing parenthetical of role rules is dense but each clause carries distinct information; only minor readability is lost.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-identifier mutation with no output schema, the description covers authorization but leaves the core mechanics of the operation (what reparenting means, null-parent handling, impact on child nodes) unexplained, and the 0%-coverage schema means nothing else fills that gap. Marginally adequate rather than complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for three required UUID parameters, and the description supplies no parameter-level meaning: it never explains that nodeId identifies the node being moved or that parentId sets its new location (and that null likely means root). With low coverage the description had to compensate and does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Move a process landscape node'), which distinguishes it from siblings like updateClarityLandscapeNode (edit properties) and organizeClarityProcessLandscape (bulk layout). It does not explicitly name those alternatives, but the action itself is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The sentence lists role preconditions for acting on different node types, which implies who may call it, but gives no guidance on when to choose this tool over siblings such as updateClarityLandscapeNode, reorderClarityLandscapeAreas, or organizeClarityProcessLandscape. No when-not or alternative routing is provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

setClarityLandscapePrioritiesSet Clarity Landscape PrioritiesB
DestructiveIdempotent
Inspect

Set or clear heatmap priorities in one batch (team managers for their processes; organization admin+ across the organization)

NameRequiredDescriptionDefault
org_idYesOrganization whose landscape is being assessed.
prioritiesYesProcess priority updates applied atomically.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so the agent knows this mutates landscape state and can be retried safely. The description adds role-based authorization context that annotations do not cover, but it does not say whether existing priorities are replaced wholesale or merged, which matters for a destructive batch write.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the action first and the authorization scope in parentheses; nothing is wasted. The parenthetical is dense but still readable, so 4 rather than 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool with full schema coverage, no output schema, and annotations covering the destructive/idempotent profile, the description is close to sufficient. The one meaningful gap is overwrite semantics for existing priority assessments, which an agent would want to know before issuing a batch write.

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%, and the schema itself documents org_id, node_id, priority enum/null-clears, reasoning, and the size bounds. The description adds only 'in one batch', so the schema does the heavy lifting and the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb pair (set/clear), the resource (heatmap priorities on the process landscape), and the batch scope, so it is distinguishable from siblings such as setClarityLandscapeNodePlacement or updateClarityLandscapeNode. It does not explicitly name those siblings, which keeps it at 4 rather than 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical gives real usage context by stating who may call it (team managers for their own processes; organization admin+ org-wide), which implies scope of use. It never states when to prefer this over a sibling tool or what happens on partial failure, so guidance remains implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

setPulseDashboardCommentResolutionSet Pulse Dashboard Comment ResolutionA
Destructive
Inspect

Mark a Duvo Pulse dashboard comment thread complete, or reopen it (requires view access). Pass the target state in resolved; the call is idempotent, and the response carries the thread with resolved_at and resolved_by set or cleared.

NameRequiredDescriptionDefault
resolvedYes
commentIdYes
artifactIdYes

TDQS

A3.5/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description explicitly asserts 'the call is idempotent', but the annotations declare idempotentHint=false. That is a direct contradiction on a declared behavioral trait, which per the rubric forces a 1 even though the description also usefully adds the view-access requirement and the response shape (resolved_at/resolved_by).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, dense but mostly waste-free, and it packs access requirements and return behavior into a compact statement. The single long sentence is slightly overloaded with semicolon clauses but earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description helpfully characterizes the response (thread with resolved_at/resolved_by set or cleared) and states the access requirement. It is largely complete for a 3-parameter mutation, aside from the untrusted idempotency claim.

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 0%, so the description must carry parameter meaning. It explains the semantics of `resolved` ('Pass the target state in `resolved`') but says nothing about `artifactId` or `commentId` beyond their UUID types in the schema, leaving half the intent to inference.

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?

States a specific verb ('Mark ... complete') plus the inverse ('or reopen it') applied to a precisely named resource ('Duvo Pulse dashboard comment thread'). An agent can immediately distinguish this from sibling comment tools like createPulseDashboardComment or deletePulseDashboardComment.

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?

Covers both directions of use (complete vs. reopen) and states the access prerequisite ('requires view access'). It does not name an alternative tool or an explicit when-not-to-use condition, which keeps it short of a 5, but the usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

setupClarityFoldersFromLandscapeSetup Clarity Folders From LandscapeBInspect

Create one linked folder per landscape group node containing this team's processes. Idempotent: groups that already have a linked folder are skipped.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

B3.3/5.0
Behavior1/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotation Contradiction: the description explicitly claims 'Idempotent: groups that already have a linked folder are skipped,' yet idempotentHint=false in the annotations. Per rubric, a direct contradiction forces a score of 1 despite the text otherwise adding useful behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with zero filler. The core action is front-loaded and the idempotency qualifier earns its place as essential behavioral context. Exceptionally tight for the information conveyed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-optional-param tool with full schema coverage, the basics are covered: scope, behavior, and skip semantics. However, there is no output schema and the description omits what the tool returns, and the idempotency contradiction undermines reliability. Adequate with clear gaps.

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 coverage is 100%; team_id is fully documented in the input schema with type, format, pattern, and auth-context behavior. The description adds no parameter-level detail, so the baseline 3 applies.

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?

States a specific verb ('Create') and resource ('one linked folder per landscape group node') with a scoping qualifier ('containing this team's processes'). This differentiates it from generic folder tools like createClarityFolder and listClarityFolders in the sibling list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies its use case — batch scaffolding of folders from a landscape — but never explicitly states when to use it over createClarityFolder or how it relates to listClarityFolders/updateClarityFolder. No when/when-not guidance or named alternatives are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

setUpModuleSet Up ModuleA
Destructive
Inspect

Set up a Duvo Module (a ready-made solution such as AP Invoice Intake & Routing or Freight Audit) as a new Automation on the team, the same as pressing Set up on the Module in the web app. Creates the Module's Agents, code steps, Queues, Policy and dashboards in one call. If the team already has a demo of this Module open, the call is refused with 409 unless convert_existing_demo is true; then that demo becomes the Automation and its sample cases and Runs are deleted, so ask the user first. The Automation starts in setup and does not run yet: call getAutomationReadiness next to see what is left of the setup, the Policy questions, the current process and the automation proposal, whose approval builds the automation. Connections and routing come once the approved proposal is being built, so don't raise them before. Give the user the url.

NameRequiredDescriptionDefault
slugYesModule template to set up, for example `ap-invoice-intake-routing` for AP Invoice Intake & Routing or `freight-audit` for Freight Audit.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
convert_existing_demoNoSet true only after the user agreed to it: when the team already has a demo of this Module open, that demo becomes the Automation and its sample cases and Runs are deleted, with no undo. Left false, such a call is refused with 409 and nothing changes.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses that the created Automation starts in setup and does not run yet, that the 409 refusal leaves state unchanged, and that convert_existing_demo deletes sample cases and Runs with no undo. The destructiveHint annotation is corroborated and made specific rather than merely restated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, then the refusal semantics, then the required next step — a logical order with no filler sentences. It is dense and longer than typical, but each clause carries operational information.

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?

No output schema exists, yet the description still tells the agent to give the user the `url`, and it covers the post-call state ('starts in setup'), the next tool to call, and the deferred setup phases. Nothing needed to invoke or follow up correctly is missing.

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 schema already explains slug, team_id and convert_existing_demo in detail. The description reinforces the convert_existing_demo consequence and the team-scoping context, but adds little syntax or format detail beyond the structured fields — baseline 3 applies.

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?

States a specific verb and resource ('Set up a Duvo Module ... as a new Automation on the team') and grounds it in a concrete UI action, with named examples (AP Invoice Intake & Routing, Freight Audit). It also lists what the call materializes (Agents, code steps, Queues, Policy, dashboards), which distinguishes it from generic siblings like createAutomation or buildClarityAutomation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit sequencing: call getAutomationReadiness next, and don't raise connections/routing until the approved proposal is being built. It also gives a hard precondition for convert_existing_demo ('ask the user first') and explains the 409 refusal path, so an agent knows both when to use it and when not to.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

startClarityExportStart Clarity ExportCInspect

Start a Clarity → SAP Signavio export job

NameRequiredDescriptionDefault
bpmnXmlYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
processIdYes
processOwnerRefNo
processApproverRefNo
connectionInstanceIdYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey that this is a mutation (readOnlyHint=false, destructiveHint=false). The description adds almost nothing beyond that — it doesn't disclose that this kicks off an asynchronous job, whether the export is polled afterward, or how to track completion. No contradiction with annotations, but minimal added behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, clean sentence with no wasted words — structurally sound. However, it borders on a restatement of the title ('Start Clarity Export'), so the conciseness is partly a function of under-specification rather than efficiency.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a moderately complex tool with 6 parameters (3 required) and no output schema, yet the description provides no guidance on the meaning of the inputs, the nature of the export job, or how to verify the result. An agent has insufficient context to call this correctly without probing other tools or schemas.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 17% (only team_id has a description), and the description explains zero parameters. The required bpmnXml, processId, and connectionInstanceId are entirely undocumented in both the description and schema. With such low coverage, the description was obligated to compensate and failed to do so.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear action ('Start') and a specific resource ('Clarity → SAP Signavio export job'). The directionality distinguishes it from generic export tools like exportCases. However, it doesn't explicitly differentiate from closely-related siblings such as getClarityExport or listActiveClarityExports, which share the export domain.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus alternatives like getClarityExport, listActiveClarityExports, or exportCases. There's no mention of prerequisites (e.g., needing an existing connectionInstanceId or a saved process) or any exclusions. An agent must infer usage entirely from the tool name and schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

startNativeOAuthStart Native OAuthAInspect

Start an OAuth-based connection with a native provider (Gmail, Google Sheets, Outlook, etc.). The provider path parameter is the native OAuth provider key from listIntegrations, not the integration type. Returns an authorization URL that must be opened in a browser by a human end-user; once they grant consent, Duvo creates the matching connection and redirects the browser to the optional return_url (or the Duvo dashboard if none is provided). Poll /v2/teams/:team_id/connections to detect the new connection.

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
providerYesNative OAuth provider key, not the integration type. Use oauth_provider_key from listIntegrations (for example, google_gmail for integration type gmail, google_sheets for googlesheets, or microsoft_outlook for outlook); passing an integration type returns 404 "Unknown OAuth provider".
return_urlNoWhere to send the user's browser after OAuth completes.
reconnect_instance_idNoWhen set, the OAuth flow will update the existing connection in place rather than creating a new one.

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by describing the full side-effect chain: an authorization URL is returned, a human must grant consent in a browser, Duvo then creates the matching connection, and the browser is redirected to return_url or the Duvo dashboard. It also discloses the post-consent polling step, which is essential behavioral context for an openWorld, non-idempotent operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose and then walks through the flow in a compact, information-dense paragraph. Sentences are long but each carries a distinct fact; no filler remains, though the flow description could be slightly tighter.

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?

No output schema exists, yet the description explains what is returned (an authorization URL), what the human must do with it, what side effect occurs on consent, and how to detect completion via polling. That fully covers what an agent needs to invoke and follow up on this tool.

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 schema already documents all four parameters, including the provider-key-vs-integration-type distinction and the 404 consequence. The description restates the provider guidance rather than adding new semantics, and never mentions reconnect_instance_id, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Start an OAuth-based connection with a native provider") and gives concrete examples (Gmail, Google Sheets, Outlook). The word "native" implicitly distinguishes it from the sibling MCP-OAuth flow (authorizeMcpOAuth/checkMcpOAuth), but no sibling is named outright, so the differentiation is left partly to inference.

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?

Gives clear operational context: the provider key comes from listIntegrations, the returned authorization URL must be opened by a human, and the caller should poll the connections endpoint afterward. It does not explicitly state when to prefer this over authorizeMcpOAuth or createConnection, so it stops short of full alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

startRunStart RunAInspect

Start a new agent run. Returns immediately with run info - does not wait for completion.

NameRequiredDescriptionDefault
messageNoOptional initial message to start the run with (e.g. a trigger payload or user instruction)
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
agent_idYesThe agent ID to run
sandbox_idNoOptional sandbox ID with pre-uploaded files
webhook_urlNoWebhook URL to POST events to (human_request, run_completed, run_failed, run_interrupted, run_expired)

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover safety (readOnly=false, idempotent=false, openWorld=true, destructive=false), and the description adds the key behavioral trait annotations cannot express: the call is asynchronous and returns before the run finishes. It stops short of stating whether duplicate concurrent runs are allowed or what quota/billing impact starting a run has.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, action first, async caveat second, zero filler. Every clause contributes information an agent needs before invoking.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With full schema coverage and no output schema, the definition is nearly sufficient: the agent knows it will get run info back immediately. It could be complete by pointing at how to observe the run afterward (getRun/listRuns or the webhook_url events), but that gap is minor.

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% with 5 documented parameters (including team-pinning rules, sandbox files, and webhook event types), so the schema carries the parameter burden and the description adds nothing beyond the name/schema. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (start an agent run) plus its asynchronous nature, which cleanly separates it from read-side siblings like getRun, listRuns, and listOrgRuns and from stopRun/stopBuilderRun. It does not explicitly name a sibling, but the purpose is unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Returns immediately - does not wait for completion' implies a fire-and-forget pattern and hints that results must be fetched separately, but no alternative tool is named (e.g. getRun/listRuns for polling) and no preconditions or when-not-to-use guidance is given. Usage is inferable, not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stopClarityArtifactChatConversationStop Clarity Artifact Chat ConversationA
Destructive
Inspect

Stop an in-flight artifact-chat turn. Flips the conversation back to open first so the interrupted run's late webhooks are dropped as stale, then best-effort interrupts the cc-server execution.

NameRequiredDescriptionDefault
process_idYes
conversation_idYes

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, readOnlyHint=false, so the safety profile is covered. The description adds genuine behavioral context beyond that: it explains the ordering (flips conversation to `open` first), the consequence (late webhooks from the interrupted run are dropped as stale), and the soft guarantee ('best-effort' cc-server interrupt). It omits auth/permission requirements and what state the conversation is left in afterward.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences with the state flip front-loaded ahead of the interrupt; every clause carries information (ordering, staleness handling, best-effort caveat). No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation with no output schema, the description covers the mechanism and failure semantics well enough to call it correctly. The remaining gap is parameter explanation (0% schema coverage), which an agent must infer purely from the UUID property names.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for both required parameters, so the description carries the full burden and provides nothing: it never mentions process_id, conversation_id, their UUID format, or whether either may reference a finished turn. The word 'conversation' appears only in prose, not as parameter documentation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb+resource ('Stop an in-flight artifact-chat turn'), which cleanly separates it from deleteClarityArtifactChatConversation (removes the conversation) and the list/get message siblings. It does not, however, explicitly name those alternatives or contrast its scope against them, so the differentiation is inferable rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'in-flight' implies the condition for use (a turn is currently running), but there is no explicit when-to-use guidance, no statement of when NOT to use it, and no pointer to delete/list alternatives. Usage is implied rather than directed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stopClarityProcessSnapshotStop Clarity Process SnapshotA
Destructive
Inspect

Stop an in-flight snapshot generation for the selected kind. Reads the sandbox id from the process row, kills the sandbox, flips the process back to review, and clears the sandbox marker so any late webhook from the killed run is dropped as stale.

NameRequiredDescriptionDefault
kindYesSnapshot kind to list
process_idYesThe clarity process id

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=false, but the description adds substantial context beyond them: it reads the sandbox id from the process row, kills the sandbox, flips the process back to `review`, and clears the sandbox marker so late webhooks from the killed run are dropped as stale. This is exactly the side-effect detail an agent needs before invoking a destructive tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single dense sentence that is front-loaded with the action and then enumerates side effects in order. Every clause carries information, though the run-on structure slightly reduces scannability compared to a tighter split of action vs. effects.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter destructive tool with no output schema, the description fully explains the observable consequences and the webhook-staleness rationale. It omits preconditions (e.g., required process state or permissions on the sandbox) and what happens if the snapshot is no longer in flight, which would complete the picture.

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 both parameters (process_id, kind) are already documented in the schema, including the enum values for kind. The description references 'the selected kind' and the process row but adds no syntax or format detail beyond what the schema provides, making the baseline 3 appropriate.

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?

States a specific verb and resource with scope: 'Stop an in-flight snapshot generation for the selected kind.' An agent can distinguish this from generateClarityProcessSnapshot, getClarityProcessSnapshot, promoteClarityProcessSnapshot, and revertClarityProcessSnapshot without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'in-flight' snapshots, so the agent knows this applies only to running generations. However, no alternatives are named (e.g., revert vs. stop vs. postprocess) and no explicit when-not-to-use guidance is given, leaving routing against the many sibling snapshot tools to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stopPulseDashboardMessageStop Pulse Dashboard MessageA
Destructive
Inspect

Stop an in-flight Duvo Pulse generation turn. Requires edit access to the dashboard. Flips the dashboard to 'interrupted' and keeps any streamed-so-far reply; stopping when nothing is generating is a successful no-op.

NameRequiredDescriptionDefault
artifactIdYes
partial_textNoThe assistant text streamed so far, kept in the conversation as the partial reply. Omit when calling from an API client without streaming state.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false, idempotentHint=false, so the safety profile is covered. The description adds genuine context beyond them: the dashboard is flipped to 'interrupted', the streamed-so-far reply is preserved rather than discarded, and stopping with no active generation is a successful no-op. Return value is not described, but that is a minor gap for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short clauses, front-loaded with the action, followed by the permission requirement and the state/retention semantics. Every sentence earns its place with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter destructive mutation with no output schema, the description covers the trigger, permission, resulting state, data retention, and no-op behavior well. The remaining gaps are parameter meaning (especially the undescribed artifactId) and any indication of what the call returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 50%: partial_text is documented in the schema, but artifactId carries no description at all. The tool description never mentions either parameter, so it does not clarify what artifactId identifies (the dashboard, the message, or the generation turn) nor when to supply partial_text, leaving the schema to carry a burden it only half meets.

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?

States a specific verb and resource with scope: 'Stop an in-flight Duvo Pulse generation turn.' An agent can distinguish this from siblings like stopRun, stopClarityProcessSnapshot, and stopClarityArtifactChatConversation because the target (a Pulse generation turn) is named explicitly.

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?

Gives a clear precondition ('Requires edit access to the dashboard') and an implicit trigger condition (an in-flight generation turn), plus the degenerate case where stopping nothing is a successful no-op. It does not name an alternative tool or state when not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stopRunStop RunA
Destructive
Inspect

Stop an agent run. No-op if the run is not currently running.

NameRequiredDescriptionDefault
run_idYesThe run's unique identifier

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is covered structurally. The description usefully adds the no-op-on-non-running behavior, which the annotations don't convey, but says nothing about the resulting run state, whether in-flight work is discarded, or permissions required.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, purpose front-loaded ahead of the caveat, with zero filler. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter control tool with full schema coverage and annotations covering safety, this is nearly complete. The main omission is the outcome of stopping (final run status, whether results are preserved), but with no output schema that is a minor gap.

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% with a single well-documented run_id (uuid format), so the schema carries full parameter burden. The description adds no additional meaning beyond what the schema provides; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb+resource: 'Stop an agent run.' The scope word 'agent' distinguishes it from the sibling cancelBuilderRun (builder runs), but it never explicitly names alternatives like startRun or cancelBuilderRun, so differentiation is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The no-op condition ('if the run is not currently running') implies when the tool is meaningful, but there is no explicit when-to-use vs alternatives guidance (e.g., startRun to launch, getRun to inspect, cancelBuilderRun for builder runs). Usage is implied only.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unlinkCaseLabelsUnlink Case LabelsB
Destructive
Inspect

Remove the given labels from a case.

NameRequiredDescriptionDefault
case_idYesThe case's unique identifier
queue_idYesThe queue's unique identifier
label_idsYes

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, and idempotentHint=false, so the safety profile is covered. The description adds no further behavioral context such as whether label removal is reversible, what permissions are required, or how duplicate/absent labels are handled.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted words. It is appropriately sized for the small parameter surface.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (3 required params, no output schema) and annotations cover the safety profile, so the description is minimally complete. However, it omits any mention of queue_id, a required parameter, and provides no contextual nuance for when the operation should be used.

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 67%: case_id and queue_id are documented in the schema, while label_ids lacks a description. The description clarifies that 'given labels' are removed from 'a case', which slightly maps to case_id and label_ids, but it never mentions queue_id, leaving the parameter meaning mostly to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Remove') and resource ('labels') with the target ('a case'), so an agent understands the operation immediately. It does not explicitly name or contrast with siblings like assignCaseLabels, but the verb itself differentiates from the add operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use, when-not-to-use, prerequisites, or alternative tools are mentioned. The description only restates the action without helping an agent choose between this and related label tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unlinkClarityProcessLabelsUnlink Clarity Process LabelsC
Destructive
Inspect

Remove process tags from a process.

NameRequiredDescriptionDefault
idYes
labelIdsYes

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=false, so the safety profile is covered structurally. The description adds almost nothing beyond that: it does not say what is destroyed or whether re-linking is possible, nor does it clarify that the labels themselves survive while only the association is removed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no filler, which is structurally clean. However, brevity here tips into under-specification rather than efficient communication.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent mutation with two undocumented parameters and no output schema, the description is too thin. It leaves the relationship between id and labelIds, the reversibility of the unlink, and the tool's place among label-management siblings entirely to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for two required parameters (id, labelIds). The description never mentions either parameter, so it fails to compensate for the documentation gap: the agent gets no hint that id is the process and labelIds is the set of labels to detach.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Remove process tags from a process" gives a verb (remove) and a resource (process tags), so the core action is identifiable. But it uses "tags" instead of the tool's own "Labels" terminology and does not distinguish this unlink operation from the inverse assignClarityProcessLabels or from deleteClarityProcessLabel, which removes the label itself rather than the association.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no mention of alternatives. An agent cannot tell from the description when unlinking is correct versus re-assigning or deleting a label.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unpinRevisionIntegrationConnectionUnpin Revision Integration ConnectionA
DestructiveIdempotent
Inspect

Unpin one of your connections from this build's integration slot. The connection itself is not deleted; only the binding to this slot is removed.

NameRequiredDescriptionDefault
agent_idYesAgent ID
build_idYesBuild ID
connection_idYesConnection ID to unpin
integration_idYesIntegration ID (catalog integration ID or slot ID from the list response)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses exactly what is affected: only the binding to the integration slot is removed, and the underlying connection survives. This adds valuable nuance to destructiveHint=true and gives the agent a precise mental model of the side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no wasted words. The action is front-loaded, and the clarifying non-deletion note earns its place by preventing a costly misunderstanding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple mutating operation, the description covers the essential effect and non-effect completely, and the schema covers parameters fully. It could add a bit more about prerequisites or expected result, but nothing critical is missing for an agent to call this tool correctly.

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 schema already documents all four parameters. The description adds only contextual framing ('this build's integration slot') and does not materially improve per-parameter understanding beyond what the schema provides.

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 names a specific verb ('Unpin') and a specific resource ('one of your connections from this build's integration slot'). It explicitly contrasts with deletion, which distinguishes this tool from deleteConnection and removeRevisionIntegration and clarifies its relationship to pinRevisionIntegrationConnection.

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?

The description provides clear contextual guidance: use this when you want to remove the binding but keep the connection itself. It implicitly excludes deletion use cases and clarifies the scope of the operation, though it does not explicitly name alternative sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateAgentUpdate AgentC
Destructive
Inspect

Update an agent's display name or delivery settings.

NameRequiredDescriptionDefault
nameNoNew agent display name.
pinnedNoPin the agent to the top of your agents list (true) or unpin it (false). Per-user — each viewer has their own pin. A team on Automations has no agents list for a pin to order, so a pin or unpin there is refused with a 409.
agent_idYesThe agent's unique identifier
thread_idNoThread id to associate with the agent, or null to clear.
slack_enabledNoWhether the agent is reachable via Slack.
agentic_memory_enabledNoToggle agentic memory for the agent.
microsoft_teams_enabledNoWhether the agent is reachable via Microsoft Teams.
computer_use_vpn_config_idNo"direct" to durably pin direct internet (no VPN, immune to future team-default changes), a VPN config UUID to pin that network, or null to follow the team default.
computer_use_sandbox_template_idNo"standard" to durably pin the standard Duvo desktop (immune to future team-default changes), a template UUID to pin that desktop, or null to follow the team default.

TDQS

C2.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, so the safety profile is partly covered. The description adds nothing on top: it does not explain what makes an 'update' destructive, whether omitted fields are preserved, whether partial updates are allowed, or what permissions are required. With a destructive write and no annotation-explaining context, this is a real gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence, front-loaded and free of waste, which is good. But for a nine-parameter destructive mutation tool the brevity crosses into under-specification rather than economy, so it does not earn a 4 or 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description is not required to explain returns, but it also omits mutation semantics, permission requirements, and any hint of the destructive behavior flagged in annotations. For a 9-param write tool in a large sibling set, this leaves the agent materially under-informed.

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% and the parameter docs are unusually rich (e.g., pinned explains per-user semantics and the 409 on Automations, VPN/sandbox params explain 'direct'/'standard'/UUID/null). The description only gestures at 'display name or delivery settings', so it neither adds nor detracts from the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

It names a specific verb and resource ('Update an agent'), which distinguishes it from createAgent/deleteAgent/getAgent. However, the stated scope ('display name or delivery settings') understates the schema, which also covers pinned, thread_id, agentic_memory_enabled, and computer-use VPN/sandbox pinning. An agent reading only the description would not know most of what it can change.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no routing to alternatives such as moveAgent/moveAgentsToFolder for placement changes or upsertAgentTrigger for trigger configuration. The agent must infer the boundary from sibling names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateAgentCaseTriggerUpdate Agent Case TriggerA
Destructive
Inspect

Update fields on a case trigger. Only the trigger creator or a builder/admin can disable an enabled trigger or change its queue, and only a builder/admin can change queue concurrency.

NameRequiredDescriptionDefault
enabledNoWhether the trigger is active. Disabled triggers do not dispatch runs.
agent_idYesThe agent's unique identifier
trigger_idYesThe case trigger's unique identifier
concurrencyNoConcurrency cap for the trigger's queue. The cap is queue-wide, so this affects every Agent working the queue, not just this trigger. Only 1 (run cases one at a time) or null (reset the whole queue's cap to the platform default) can be set here; higher caps are configured per-queue via PATCH /v2/admin/case-queues/{queueId}/concurrency. Omit to leave the current value unchanged.
case_queue_idNoQueue whose new cases should trigger this agent

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true and non-idempotent, so the safety bar is lower. The description adds genuinely new context the annotations don't carry: authorization tiers (creator/builder/admin) governing which fields can be changed. It could go further on what disabling does to in-flight runs, but the added permission detail is substantive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, with the core action front-loaded and the permission constraints packed into the second. No filler, though the authorization clause is a dense run-on that mixes three separate conditions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter mutation with no output schema, the definition supplies the action, the field categories affected, and the permission model. Return behavior is unspecified, but the schema already covers parameter detail, leaving only minor gaps.

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 each of the five parameters is already documented in detail, including the queue-wide concurrency caveat. The description's mention of queue/concurrency changes parallels but does not extend the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Update fields on a case trigger'), which clearly distinguishes it from the delete/get/list trigger siblings. It stops short of explicitly naming the alternative tools, but the action and target are unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence gives real prerequisites (who may disable a trigger, change its queue, or change concurrency), which is useful before invoking. However, it never says when to use this versus upsertAgentTrigger, previewAgentCaseTriggerConflicts, or deleteAgentCaseTrigger, so alternative selection is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateAgentFolderUpdate Agent FolderA
Destructive
Inspect

Rename an agent folder or move it to a new parent.

NameRequiredDescriptionDefault
nameNoNew folder name
folder_idYesThe folder's unique identifier
parent_folder_idNoNew parent folder ID. Pass null to move the folder to the root level.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, so the safety profile is carried by structured data. The description adds the useful distinction between the two mutation modes (rename vs. move) but says nothing about side effects of moving, permission requirements, or reversibility.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler; both supported operations are stated up front and nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter mutation whose annotations already cover the destructive/idempotency profile and whose schema is fully documented, the description is nearly sufficient. The only real gap is not clarifying that supplying neither name nor parent_folder_id results in a no-op.

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 name, folder_id, and parent_folder_id are already documented, including the null-to-root behavior. The description only restates the rename/move mapping to those parameters, adding no syntax or edge-case detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource with the two supported operations ('rename an agent folder or move it to a new parent'), which cleanly separates it from createAgentFolder, deleteAgentFolder, and listAgentFolders. It does not explicitly contrast with the similarly-named moveAgentsToFolder or moveAutomationsToFolder siblings, but the resource is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the operation itself, but there is no explicit when-to-use, no prerequisites, and no routing guidance against siblings like moveAgent or moveAgentsToFolder. It also fails to note that at least one of name/parent_folder_id must be supplied, since only folder_id is required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateAutomationUpdate AutomationB
Destructive
Inspect

Update an automation, e.g. rename it. Only the fields present in the body are changed.

NameRequiredDescriptionDefault
nameNoNew human-readable automation name.
automation_idYesAutomation ID

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, and idempotentHint=false, so the safety profile is known. The description adds genuine value by disclosing partial-update semantics ('only the fields present in the body are changed'), but says nothing about permissions, reversibility, or the tension between a patch-style update and destructiveHint=true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and immediately followed by the key behavioral constraint. Every clause carries weight; only the 'e.g. rename it' example is mildly redundant given name is the sole optional field.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter update tool with full schema coverage and annotations, the description covers the essential patch semantics and needs no return-value explanation (no output schema). Missing only edge detail like permission requirements, which is acceptable at this complexity.

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% – both name and automation_id are documented in the schema with constraints (uuid pattern, maxLength). The description hints at the rename use case but adds no format or syntax detail beyond what the schema already provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Update an automation') and gives a concrete example ('rename it'). It does not, however, differentiate itself from close siblings such as updateAutomationTabs or moveAutomationsToFolder, so an agent must rely on the name alone to disambiguate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance, no prerequisites, and no naming of alternatives. The sentence about only present fields changing describes mechanics rather than selection criteria, so an agent gets no help deciding between this and sibling update/move/duplicate tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateAutomationTabsUpdate Automation TabsA
DestructiveIdempotent
Inspect

Replace the automation detail view's tab arrangement. Pinning, unpinning, reordering and hiding a tab are all expressed as a different arrangement.

NameRequiredDescriptionDefault
orderYesLeft-group tab keys in render order
hiddenYesNative tab keys the user removed from the bar
automation_idYesAutomation ID

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false, so the safety profile is covered structurally. The description adds real value beyond that by making the replace semantics explicit — the existing arrangement is overwritten wholesale rather than patched — which is the key behavioral fact for avoiding accidental tab loss. It does not mention permissions or partial-failure behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler, with the core action front-loaded and the semantics of the operation immediately following. Nothing is repeated from the title or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter, fully-required mutation with rich annotations and no output schema, the description supplies the one thing the schema cannot: that this is a whole-arrangement replacement. It is complete enough to invoke correctly, though it does not state whether omitted keys are implicitly unhidden or whether the call fails on unknown tab keys.

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%, with 'order' and 'hidden' each carrying their own description ('Left-group tab keys in render order', 'Native tab keys the user removed from the bar'), so the schema does the heavy lifting. The description adds the conceptual framing that both arrays together constitute the arrangement, but no syntax or key-format detail beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Replace the automation detail view's tab arrangement.' An agent can immediately tell this is a full-state write of the tab layout, distinct from the read-side sibling getAutomationTabs. It stops short of naming that sibling or any other alternative, so it is clear but not sibling-differentiating.

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?

The second sentence is genuine usage guidance: it tells the caller that pinning, unpinning, reordering and hiding are all expressed as a different arrangement, i.e. there are no separate pin/reorder operations and the caller must supply complete desired state. It gives clear context but no explicit when-not-to-use or named alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateCaseUpdate CaseA
Destructive
Inspect

Edit a case's title and/or its data payload. Provide at least one field. For the payload, send free-form data OR a structured json_data object, never both. json_data is validated against the queue's Case schema and requires the queue to have one; a case that is already typed against a schema keeps its structured payload and rejects a free-text data write. Works on pending, in-progress, and settled cases. Other attributes (status, priority, labels) have their own dedicated endpoints. Returns the updated case with its event history and approval batches.

NameRequiredDescriptionDefault
dataNoNew free-form data payload handed to the agent when the case is claimed. Mutually exclusive with `json_data`.
titleNoNew case title (1–500 characters).
case_idYesThe case's unique identifier
json_dataNoNew structured payload for a case on a queue that has a Case schema. Validated against that schema and mutually exclusive with `data`.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only carry the safety flags (destructive=true, idempotent=false); the description adds substantive behavior beyond them: json_data is validated against the queue's Case schema and requires that schema to exist, and a schema-typed case rejects a free-text data write. It also discloses the return contents (updated case with event history and approval batches).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and required-field constraint, then layers the payload rules and exclusions. Every sentence carries information, though the mutual-exclusivity point is stated twice (once in prose, once reinforced), making it slightly denser than strictly necessary.

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?

A mutation tool with no output schema, but the description covers return values (updated case plus event history and approval batches), the payload constraints, applicability across case states, and the sibling routing. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3 and the schema already documents each field. The description adds real value on top: the never-both rule, the queue-must-have-a-schema requirement for json_data, and the type-locking behavior that rejects data writes on schema-typed cases.

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?

States a specific verb (edit) plus resource (case) and scoped fields (title and/or data payload). It explicitly separates itself from siblings: 'Other attributes (status, priority, labels) have their own dedicated endpoints,' ruling out bulkUpdateCaseStatus/bulkUpdateCasePriority/assignCaseLabels. An agent can route without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit preconditions ('Provide at least one field'), mutual-exclusion rules (data OR json_data, never both), and the case states it applies to (pending, in-progress, settled). It also names the excluded attribute categories and where they live, which is exactly the when-not guidance needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateCaseQueueEvalRubricUpdate Case Queue Eval RubricA
Destructive
Inspect

Edit a single case-level evaluation rubric's title and/or description. The edit produces a NEW rubric (with a new id and slug) so previously judged cases stay attributed to the original criterion; the response contains the new rubric.

NameRequiredDescriptionDefault
titleNoShort, human-readable Pass/Fail rubric title.
queue_idYesThe queue's unique identifier
rubric_idYesThe case-level rubric's unique identifier
descriptionNoA 1-2 sentence Pass condition phrased as a question.

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already signal mutation/destructiveness, but the description adds critical behavior beyond them: the update creates a NEW rubric with a new id and slug, preserves attribution of previously judged cases, and returns the new rubric. This is valuable context that prevents an agent from assuming an in-place update.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The first sentence states the action and scope, and the second delivers the critical side-effect information about new IDs, attribution preservation, and the response. Every clause earns its place.

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 4-parameter mutation tool with full schema coverage and annotations, the description covers the essential missing piece: the non-obvious create-new-rubric behavior and the response shape. No output schema exists, but the description explicitly states the response contains the new rubric, making the tool sufficiently complete for correct invocation.

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 coverage is 100%, and the schema already documents all four parameters with descriptions and constraints. The description adds no parameter-specific meaning beyond naming title and description as the editable fields, so the baseline of 3 applies.

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 uses a specific verb ('Edit') with a clearly defined resource ('a single case-level evaluation rubric's title and/or description'). It distinguishes this tool from siblings like createCaseQueueEvalRubric, replaceCaseQueueEvalRubrics, and deleteCaseQueueEvalRubric by emphasizing 'single' and 'case-level', so an agent can select it without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for editing only the title and/or description of a single case-level rubric, and it explains a key condition: the edit produces a new rubric so previously judged cases stay attributed to the original criterion. However, it does not explicitly name alternatives or state when-not-to-use, so guidance is implied rather than fully explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityFolderUpdate Clarity FolderA
Destructive
Inspect

Rename a process folder. Renaming a landscape-linked folder permanently stops landscape name-sync.

NameRequiredDescriptionDefault
nameYesNew folder name.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
folderIdYesFolder to rename.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already flag this as non-read-only, non-idempotent, and destructive. The description adds genuinely new context beyond annotations: renaming a landscape-linked folder "permanently stops landscape name-sync," an irreversible side effect an agent could not infer from structured fields. It does not describe permissions or the response, keeping it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero waste. The core action is front-loaded and the destructive side-effect caveat immediately follows, so nothing needs to be re-read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple rename with full schema coverage, no output schema, and annotations carrying the safety profile, the description covers what the tool does and the one non-obvious irreversible consequence. It omits any auth/team-scoping guidance, but that lives in the schema.

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 folderId, name, and the non-obvious team_id fallback/rejection behavior are all documented in the schema. The description adds no syntax or constraint detail beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Rename a process folder") that distinguishes it from createClarityFolder, deleteClarityFolder, and reorderClarityFolders. It also clarifies beyond the generic title "Update Clarity Folder" that the only operation is a rename. Sibling alternatives are not named, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: call this to rename a folder. There is no explicit when-to-use, when-not-to-use, or pointer to sibling tools (e.g. moveClarityProcessesToFolder for relocation), and no stated prerequisites such as required permissions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityGuidanceUpdate Clarity GuidanceC
Destructive
Inspect

Update the automation guidance message for a clarity process

NameRequiredDescriptionDefault
idYesThe clarity process ID
contentYesReplacement automation guidance for the process.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is covered structurally. The description adds nothing beyond that: it doesn't state that the previous guidance is overwritten, whether the process must already have guidance, or what permissions are needed. For a destructive mutation it is thin on behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no wasted words and the key noun phrase up front. It is efficient, though its brevity borders on under-specification rather than tight conciseness.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter destructive update with full schema coverage and no output schema, the annotations carry the safety profile and the schema carries the parameters. However, the description omits whether the process must already have guidance, whether the write is replace-in-full, and any error/authorization context, leaving real gaps for a destructive mutation.

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% — both 'id' (clarity process ID) and 'content' (replacement guidance, max 5000 chars) are fully documented in the schema. The description adds no parameter meaning beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Update) and resource (the automation guidance message for a clarity process), which is clear enough for an agent to act on. It doesn't explicitly differentiate from sibling createClarityGuidance, but the verb+resource pairing makes the create-vs-update distinction inferable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, prerequisites, or alternatives are provided. The agent must infer that this is used to modify existing guidance rather than create new guidance (createClarityGuidance) from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityLandscapeNodeUpdate Clarity Landscape NodeA
Destructive
Inspect

Rename a process landscape node or update its owner label (team manager or above for team processes; organization admin for areas)

NameRequiredDescriptionDefault
nameNo
orgIdYes
nodeIdYes
ownerLabelNo

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds genuinely new behavioral context beyond annotations: the role-based authorization requirement, which differs by node type (team process vs area) and is not present in the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence states the action before the parenthetical permission qualifier, with no filler. The nested parenthetical is slightly dense to parse but every clause earns its place by adding an authorization rule.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-field mutation with no output schema, the description covers the action, the fields, and the permission gate. It stops short of explaining null-clearing of ownerLabel or the interaction with placement siblings, but the annotations and schema carry enough that an agent can call it correctly.

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 0%, so the description carries the burden. It names the two mutable fields ('name' via rename, 'ownerLabel') and clarifies that ownerLabel is a team/area ownership label, but adds nothing about orgId/nodeId semantics and does not explain that ownerLabel accepts null to clear it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb pair ('Rename ... or update its owner label') against a precise resource ('process landscape node'), so an agent knows exactly which fields this mutation targets. It implicitly distinguishes itself from siblings like setClarityLandscapeNodePlacement and updateClarityLandscapeNodePerson, but never names them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It supplies a use condition in the form of permissions ('team manager or above for team processes; organization admin for areas'), which tells the agent whether the caller is likely authorized. However, it never contrasts this tool with the adjacent siblings (placement, person updates) or states when not to use it, leaving the alternative-routing decision to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityLandscapeNodePersonUpdate Clarity Landscape Node PersonB
Destructive
Inspect

Change the role a person plays in the process behind a process landscape node (for example "Approver"). Send role: null to clear it.

NameRequiredDescriptionDefault
roleNo
orgIdYes
nodeIdYesA process landscape node that is linked to a real process.
teamIdNo
personIdYesThe person entry to change, as returned by listClarityLandscapeNodePeople.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, so the mutation profile is covered. The description adds useful behavioral context about null clearing semantics, but says nothing about what happens to the prior role or whether the person must already be attached to the node.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, both earning their place, with the primary action stated first and the edge-case (null) instruction second. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive 5-parameter mutation with 40% schema coverage and no output schema, the description handles the role parameter and clearing semantics but omits scope parameters (orgId, teamId) and any note about side effects or prerequisites.

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 coverage is only 40% (nodeId and personId documented, orgId/teamId/role not). The description compensates well for `role` by explaining the null-clearing behavior and giving an example value, but leaves orgId and teamId entirely unexplained in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Change) and a precisely scoped resource (the role a person plays in the process behind a landscape node), with a concrete example ("Approver"). It is clearly distinguishable from add/removeClarityLandscapeNodePerson and updateClarityLandscapeNode, though it doesn't name those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The instruction 'Send role: null to clear it' is genuine usage guidance for the clearing case, but there is no statement of when to prefer this tool over siblings like addClarityLandscapeNodePerson or updateClarityLandscapeNode, and no prerequisites or permission context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityOrganizationInterviewUpdate Clarity Organization InterviewC
Destructive
Inspect

Rename an organization landscape Clarity capture

NameRequiredDescriptionDefault
orgIdYes
titleYes
interviewIdYesThe organization interview ID

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, and idempotentHint=false, so the safety profile is covered by structured data. The description adds nothing beyond that: it does not explain why a mere rename is flagged destructive, whether the old title is lost, or any auth/permission requirement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with the verb front-loaded and zero filler. It is appropriately sized, though its brevity is partly why other dimensions are under-served.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent mutation with no output schema and only 33% parameter documentation, the description omits usage guidance, parameter roles, and behavioral consequences. It leaves too much for the agent to infer before making an irreversible change.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33% (only interviewId is documented) and the description supplies no parameter meaning at all. It does not clarify that orgId scopes the organization, interviewId selects the interview, or title is the new name (and its 1-160 length constraint), so it fails to compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('Rename') but the resource phrasing ('organization landscape Clarity capture') does not cleanly match the tool name ('Clarity Organization Interview') or its sibling family, and it silently narrows 'Update' to a rename only. An agent can roughly tell what it does, but the terminology drift between name, title, and description muddies the target resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus getClarityOrganizationInterview, listClarityOrganizationInterviews, finalizeClarityOrganizationInterview, or the parallel landscape/team interview update tools. No prerequisites or context are given, leaving routing entirely to inference from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityProcessUpdate Clarity ProcessA
Destructive
Inspect

Update a Clarity process name, guidance, interview independence, visibility, or completion status. Team Builders can edit names, guidance, and interview independence, only the creator or a team manager can change visibility, and completing or reopening a process for review requires a Lead Builder role.

NameRequiredDescriptionDefault
idYesClarity process id
nameNoNew process name
statusNoMark a review-stage process complete, or reopen a completed process for review
visibilityNoProcess visibility within the team
mapLanguageNoLanguage Duvo writes this process's map in, or null to use the team's map language
customPromptNoProcess-specific guidance, or null to clear it
independentInterviewsNoRun each interview independently: no briefing from earlier interviews and a neutral opener

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations supply readOnlyHint=false, destructiveHint=true, idempotentHint=false, so the safety profile is known; the description adds real value on top by disclosing the per-field authorization model (who can change names/guidance/interview independence vs. visibility vs. status). It does not explain that omitting fields leaves them unchanged or that passing null clears guidance, which matters for a destructive mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tightly packed sentences: the operations come first, then the authorization rules as a parallel clause. No filler, though the second sentence is dense enough to require a careful read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive 7-parameter mutation with no output schema, the definition covers scope and authorization adequately. Partial-update semantics (unspecified fields untouched, null clears customPrompt/mapLanguage) and the consequences of status transitions are left to the schema, which mostly carries them.

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 every parameter is already documented, including customPrompt's null-to-clear semantics and mapLanguage's null fallback. The description maps facets to roles, which adds permission meaning, but it omits mapLanguage from its field list and introduces no syntax or format detail the schema lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (update) and resource (Clarity process) and enumerates the editable facets: name, guidance, interview independence, visibility, completion status. That is enough to distinguish it from generic siblings, though it never clarifies its boundary against near-neighbors like updateClarityProcessSharing (which also touches visibility/share scope) or updateClarityGuidance (guidance also settable here via customPrompt).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is framed entirely as role permissions (Team Builder, creator/team manager, Lead Builder), which is genuinely useful gating but tells the agent who may call it, not when to prefer it. With updateClarityProcessSharing and updateClarityGuidance in the sibling list, the description should say which tool owns sharing/guidance changes; that ambiguity is left unresolved.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityProcessLabelUpdate Clarity Process LabelC
Destructive
Inspect

Update process tags for an organization.

NameRequiredDescriptionDefault
orgIdYes
valueNo
labelIdYes
colorHueNo

TDQS

C2.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, so the safety profile is covered structurally. The description adds nothing about what actually changes — whether 'value' replaces the existing label text, whether colorHue is reset, or whether the change is reversible.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no filler, but it is under-specified rather than truly concise — brevity here comes at the cost of the information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A destructive mutation with no output schema, zero parameter documentation, no usage guidance, and no description of effects leaves an agent without enough to invoke it correctly or predict consequences.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description mentions no parameters. The required labelId, plus value and colorHue, are completely undocumented anywhere; the loose phrase 'for an organization' only vaguely gestures at orgId.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a verb ('Update') and a resource ('process tags for an organization'), but calls labels 'tags' while the tool name and every sibling use 'Label', creating a terminology mismatch. It also fails to distinguish itself from close siblings such as createClarityProcessLabel, deleteClarityProcessLabel, and unlinkClarityProcessLabels.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance, no prerequisites, and no mention of alternatives. The description does not tell an agent when updating a label is appropriate versus assigning, unlinking, or deleting one.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityProcessSharingUpdate Clarity Process SharingC
Destructive
Inspect

Enable or disable sharing for a clarity process

NameRequiredDescriptionDefault
idYesClarity process ID.
enabledYesWhether public process sharing is enabled.
proposalShareEnabledNoWhether the automation proposal is included. Public sharing must already be enabled when only changing this setting.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false, and readOnlyHint=false, which tells the agent this is a mutating, non-idempotent operation. The description adds nothing on top of that — it does not explain what enabling public sharing actually exposes, whether disabling is reversible, or what permissions are required, so its contribution beyond structured fields is essentially nil.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single well-formed sentence with the action front-loaded and no filler or redundancy. It is arguably too terse rather than too long, but for the conciseness dimension specifically the text is efficient and earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent mutation with three parameters and no output schema, the description is under-specified: it omits the getClarityProcessSharing pairing, the meaning of public sharing, and the interaction between the two boolean flags. The schema carries the parameter detail, but the description does not round out the picture an agent needs before flipping a visibility switch.

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 both 'enabled' and 'proposalShareEnabled' (including the dependency rule) are fully documented in the schema; baseline 3 applies. The description only gestures at the 'enabled' parameter via 'enable or disable' and says nothing about the proposal-sharing sub-setting or its ordering constraint.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb pair (enable/disable) plus the resource (sharing for a clarity process), so the agent knows exactly what state this tool mutates. It does not, however, name or differentiate itself from the sibling read tool getClarityProcessSharing, so sibling discrimination must come from the name alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus getClarityProcessSharing (to inspect current sharing state) or updateClarityProcess, nor any prerequisite called out in the description. The only conditional logic (public sharing must already be enabled before toggling proposalShareEnabled) lives in the schema, not here.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateClarityTeamSettingsUpdate Clarity Team SettingsC
Destructive
Inspect

Update clarity team settings for financial calculations

NameRequiredDescriptionDefault
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
industryNo
languageNo
teamSizeNo
companyNameNo
mapLanguageNo
annualRevenueNo
averageHourlyRateNo
emailReportsEnabledNo
emailReportIncludeSummaryNo
emailReportIncludeCapturesNo

TDQS

C2.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, and idempotentHint=false, so the safety profile is covered structurally. The description adds nothing behavioral beyond that: it doesn't say whether updates are partial or replace-all, whether omitted fields are cleared, or what permissions are needed for a destructive mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with no filler and the core action front-loaded, but its brevity comes from omission rather than economy — it is under-specified for an 11-parameter mutation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, non-idempotent mutation with 11 parameters at 9% schema coverage and no output schema, the description supplies none of the missing context (partial vs. full update semantics, field meanings, team_id pinning behavior that only the schema explains). It is not sufficient to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 9% — only team_id is documented, leaving 10 parameters (industry, companyName, annualRevenue, averageHourlyRate, the email-report flags, etc.) with no descriptions anywhere. "Financial calculations" faintly gestures at the money-related fields but conveys no real semantics, so the description does not compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a verb and resource ("Update clarity team settings") but it essentially restates the title, and the qualifier "for financial calculations" is vague about which settings are affected. It does not differentiate against the obvious sibling getClarityTeamSettings or clarify scope beyond the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no prerequisites, and no mention of the read-side alternative getClarityTeamSettings. The agent must infer from the name alone that this is the mutation counterpart.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateConfigFieldUpdate Config FieldA
Destructive
Inspect

Set or clear a config field's value. value: null removes the answer and does not restore the module default, so a Run that reads the field is refused until it is answered again. To use the default, send default_value as value. On a running automation (running in readAutomationPolicy) the change reaches its Agents from their next run: name the question, its current answer and the new one, change it only after the user says yes, and pass the current answer you showed, not the new one, as expected_value so a change someone made in between is not overwritten. A compound question takes every part in one write. When the field's bindings include structural, the module's Agents also need a matching change; propose it.

NameRequiredDescriptionDefault
valueYes
fieldIdYesConfig field ID
automationIdYesAutomation ID
expected_valueNoThe current answer, as you read it and showed the user, not the new one (null if it was unanswered). If the answer has changed since, nothing is written and the call fails with 409; read the Policy again

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructive=true and non-idempotent, and the description adds far more: that a null removal does not restore the module default and causes reads to be refused, that changes propagate to Agents on their next run, and that a 409 occurs on stale `expected_value`. These are precisely the side effects an agent needs before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action is front-loaded in the first clause, and every following sentence covers a distinct constraint (null semantics, defaults, running-automation protocol, structural bindings). It is dense and long, but no sentence is filler.

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 destructive mutation with no output schema, the description covers side effects, the confirmation workflow, the concurrency failure mode, and the structural-binding follow-up. Nothing an agent needs to call it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75% and already documents `expected_value` and the IDs. The description adds real semantic value for `value` (null vs default_value vs compound-question single write) and reinforces the optimistic-concurrency meaning of `expected_value`, going beyond the raw schema.

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 opening sentence gives a specific verb+resource ('Set or clear a config field's value') and the scope covers both write modes. It distinguishes this from siblings like addConfigField, updateConfigFieldDefinition, hideConfigField, and restoreConfigField by specifying this is the value-setting operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives rich conditional guidance: use `value: null` to remove an answer, send `default_value` as `value` to restore the default, and follow a specific confirmation protocol on a running automation (name the question, get user consent, pass the shown answer as `expected_value`). It also names `readAutomationPolicy` as the source of policy state.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateConfigFieldDefinitionUpdate Config Field DefinitionA
Destructive
Inspect

Edit a Policy question: its label, question, guidance, example answer, section, the roles that answer it, the options of a select or multiSelect field, and the columns of an unanswered table field a person added. A reworded question gets a new version, and a new section moves the field to that section's end. The type of a field added through the API can change while it has no answer; a field from the module template keeps its type. The answer is never changed, and a module template reinstall keeps the edit.

NameRequiredDescriptionDefault
keyNoNew code, only for a field added to this automation that no Agent or Code step reads yet
typeNoNew value type, only for a field added through the API that has no answer yet
labelNoShort name for the field, shown as its row heading
rolesNoKeys of the process roles whose holders answer this question; replaces the whole list, and empty means anyone
columnsNoTable fields only, while the field has no answer; replaces the whole list
exampleNoNew example answer, or null to remove it
optionsNoSelect and multiSelect fields only; replaces the whole list
sectionNoSection to move the field to the end of, or null for none
field_idYesThe config field's unique identifier
guidanceNoNew guidance on what to fill in, in plain sentences, or null to remove it
questionNoNew question; a reworded question gets a new version
automation_idYesThe automation's unique identifier

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already flag destructiveHint=true, readOnlyHint=false and idempotentHint=false, but the description adds meaningful side-effect context: rewording spawns a new version, a new section relocates the field to that section's end, answers are never modified, and template reinstall preserves the edit. It stops short of stating required permissions, keeping it at a strong 4 rather than 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the edit scope, then the behavioral constraints, with essentially no filler. It is dense and slightly long, but each sentence carries distinct information; only minor tightening is possible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter mutation with no output schema, the description supplies the versioning, ordering, and immutability semantics an agent needs to call it safely. It omits what the call returns and any permission requirements, which keeps it from a 5.

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 schema already documents every parameter thoroughly. The description mostly restates the same fields and adds only minor nuance (columns belong to 'an unanswered table field a person added'), which does not meaningfully extend the schema. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb (Edit) plus resource (a Policy question / config field definition) and enumerates the editable facets (label, question, guidance, example, section, roles, options, columns). It is clear what the tool does, but it never distinguishes itself from the very close sibling updateConfigField, leaving the agent to guess which update variant applies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied through conditional constraints (reworded question gets a new version, API-added field's type can change, template field keeps its type). There is no explicit statement of when to reach for this tool versus updateConfigField or addConfigField, so the agent must infer the situation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateConnectionUpdate ConnectionA
Destructive
Inspect

Update an existing connection. For sensitive header values, sending an empty string keeps the existing value; send a new value to overwrite. Toggling shared moves the connection between personal and team-shared.

NameRequiredDescriptionDefault
nameNo
sharedNo
headersNo
server_urlNo
auth_methodNo
connection_idYesConnection ID

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is covered. The description adds genuinely non-obvious behavior: empty-string honors a partial-update for sensitive headers, and `shared` toggling migrates the connection between personal and team scope. This is real value beyond annotations, though it doesn't fully explain mutation consequences for other fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the core purpose, then the two highest-value behavioral notes. No filler; each sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given annotations already cover the safety profile and there is no output schema to explain, the description covers the tricky non-obvious behaviors well. It stops short of addressing auth_method/server_url change semantics or name uniqueness, but nothing critical for calling it correctly is missing.

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 only 17%, so the description must carry meaning. It adds real semantic detail for `headers` (empty-string keep semantics) and `shared` (scope migration), but leaves name, server_url, auth_method, and connection_id unexplained beyond the schema's bare type/format.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Update an existing connection'), which cleanly separates it from createConnection, deleteConnection, and getConnection siblings by verb. It does not, however, explicitly name which sibling it replaces or how it differs from e.g. updateCredential/updateSecret.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through its semantics but gives no explicit when-to-use vs alternatives guidance (e.g., updateConnection vs deleteConnection+createConnection, or when to prefer update over create). Usage context is inferable from the name but not spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateCredentialUpdate credential by idA
Destructive
Inspect

Update a login by id. At least one of password or otp_secret must remain set after the update. Editing a team-shared login or toggling sharing requires lead builder role.

NameRequiredDescriptionDefault
idYes
domainNo
sharedNo
userIdYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
passwordNo
usernameNo
otp_secretNo

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the mutation profile (destructiveHint=true, idempotentHint=false), so the bar is lower. The description adds substantive business rules beyond the annotations: the password/otp_secret invariant and the lead-builder-role requirement for team-shared edits or toggling sharing. It stops short of describing exactly what is overwritten on a null-vs-omitted field.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the action, then the validation invariant and the role gate. Every sentence carries distinct information with no filler, though it could be slightly tighter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation tool with eight low-coverage parameters and no output schema, the description covers the most dangerous gotchas (password/otp invariant, role gate) but omits identifier semantics and what a null versus omitted field does. Adequate but with visible gaps.

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 coverage is only 13% (only team_id is documented), so the description must compensate. It does clarify the critical password/otp_secret nullability constraint and the meaning of the shared toggle, but leaves userId, id, domain, and username semantics entirely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Update a login by id'), which clearly distinguishes it from getCredential, createCredential, deleteCredential, and listCredentials siblings. It does not explicitly call out those alternatives, but the operation is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a real precondition ('At least one of password or otp_secret must remain set after the update') and a role gate, which implicitly tells the agent when this call will succeed. However, it offers no guidance on when to choose this over siblings or on prerequisites like first fetching the current credential.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateEvalRubricUpdate Eval RubricA
Destructive
Inspect

Edit a single Agent-specific evaluation rubric's title and/or description. The edit produces a NEW rubric (with a new id and slug) so previously scored Runs stay attributed to the original criterion; the response contains the new rubric.

NameRequiredDescriptionDefault
titleNoShort, human-readable Pass/Fail rubric title.
agentIdYesThe agent's unique identifier (Assignment ID)
rubricIdYesThe custom rubric's unique identifier
descriptionNoA 1-2 sentence Pass condition phrased as a question.
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

A3.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations by disclosing the critical non-obvious behavior: the edit creates a NEW rubric with a new id and slug, previously scored Runs remain attributed to the original criterion, and the response contains the new rubric. This is exactly the kind of behavioral nuance an agent needs and complements the destructiveHint annotation without contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, well-structured sentence. It front-loads the core action and then efficiently explains the most important consequences: new id/slug, preservation of past Run attribution, and the response containing the new rubric. There is no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of an output schema, the description does a good job of noting that the response contains the new rubric and explaining the versioning side effect. Combined with the fully documented schema, the agent has enough context to invoke the tool. It falls slightly short of complete because it does not summarize the selected_automation_revision_id draft/active behavior, though the schema covers it.

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 all parameters are already well documented, including the complex selected_automation_revision_id behavior. The description mentions title and/or description at a high level but does not add new parameter meaning beyond what the schema already provides, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action: edit a single Agent-specific evaluation rubric's title and/or description. It identifies the resource and the fields affected, so an agent can understand what the tool does. However, it does not explicitly differentiate this tool from related siblings such as createEvalRubric, replaceEvalRubrics, or updateCaseQueueEvalRubric.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for editing an existing rubric, but it gives no explicit guidance on when to use it versus creating, replacing, or deleting a rubric. No exclusions, prerequisites, or alternative tool mentions are provided, leaving the agent to infer appropriate usage from the tool name and context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateFileContentUpdate File ContentC
DestructiveIdempotent
Inspect

Update the content of a text file.

NameRequiredDescriptionDefault
pathYesPath of the file relative to the team's storage root
contentYesNew UTF-8 text content for the file
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false, destructiveHint=true, idempotentHint=true, and openWorldHint=false, so the safety profile is covered. However, the description fails to disclose the most consequential behavior for this operation: whether 'update the content' means full replacement/overwrite of the file versus a merge or append, and whether the file must pre-exist. That ambiguity matters for a destructive write.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short, front-loaded sentence with no padding or redundancy. Its brevity is structural rather than wasteful, though the terseness contributes to the gaps scored elsewhere.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 100% schema coverage and annotations carrying the safety profile, the definition is minimally complete for invocation. Still missing is the overwrite-vs-merge semantics and existence requirements, which an agent needs to use a destructive content-replacement tool correctly.

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%, and the schema already explains path, content, and the team_id fallback/rejection rules in detail. The description adds nothing beyond the schema, so the baseline of 3 for high-coverage schemas applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a verb and resource ('Update the content of a text file'), but it is essentially a restatement of the tool name and title with only the minimal addition of 'text file'. It does not distinguish this tool from siblings like updateSkillFile, updateSkillRevisionFile, or renameFile, so an agent gets no help telling them apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance, no statement of prerequisites (e.g., the file must already exist), and no mention of alternatives or complements such as getFileContent, deleteFile, or renameFile. The agent must infer everything about when this tool applies.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updatePulseDashboardUpdate Pulse DashboardB
Destructive
Inspect

Update a Duvo Pulse dashboard's settings — rename it. Only the creator can update it.

NameRequiredDescriptionDefault
titleYes
artifactIdYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare non-read-only, destructive, and non-idempotent behavior. The description adds a meaningful authorization constraint (creator-only) beyond the annotations, but does not disclose other traits such as whether renaming is reversible or what happens on conflict.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with the core operation front-loaded and no wasted words. The em-dash clarification is efficient, though the phrase slightly interrupts the sentence flow.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter tool with no output schema, the description covers the purpose and an authorization rule, which is adequate. It omits parameter-level guidance that would compensate for the fully undescribed schema, leaving a clear gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for undocumented parameters. It only hints at the title parameter via 'rename it' and says nothing about the required artifactId, UUID format, or title length constraints.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (update) and resource (Duvo Pulse dashboard's settings), and clarifies the operation is a rename. This distinguishes it from read or delete siblings, though it does not explicitly name any alternative tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an important usage constraint (only the creator can update it), which is useful guidance. However, it does not state when to use this tool versus alternatives like movePulseDashboard, publishPulseDashboard, or duplicatePulseDashboard, leaving the agent to infer context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateQueueUpdate QueueC
Destructive
Inspect

Update a queue.

NameRequiredDescriptionDefault
nameNoNew queue name. A standalone queue's name must be unique within the team, and a queue inside an automation's name must be unique within that automation. Queue names are not versioned, so this is the canonical name on any Automations workspace team, with or without revisions. A revision carrying a per-revision name override applies it over this one when that revision is activated.
queue_idYesThe queue's unique identifier
folder_idNoNew folder id, or null to move to the root.
descriptionNoNew description, or null to clear.

TDQS

C2.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is conveyed structurally. The description adds nothing on top of that: it does not say that omitted fields are left unchanged, that null clears folder/description, or that renaming has uniqueness constraints. With annotations covering the basics, this lands at 2 rather than 1.

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?

At three words the text is short but not informative—it is under-specified rather than concise. No sentence earns its place because the single sentence merely echoes the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation tool whose name field has cross-revision/versioning subtleties, the description leaves the agent without any behavioral framing. The rich schema and annotations partially compensate, but the description itself is far too thin to be considered complete.

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% and each parameter (name, queue_id, folder_id, description) is thoroughly documented in the schema, including the null-to-clear and uniqueness semantics. The description adds no parameter meaning, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose2/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Update a queue" restates the tool name and title without adding scope, effect, or distinguishing detail. It does not differentiate from close siblings such as updateQueueLabel or updateQueueJsonSchemaSettings, nor does it say which queue properties are editable. This is effectively a tautology.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus the sibling update/delete/rename variants, and no mention of prerequisites such as needing the queue_id or team/automation ownership. The agent is left to infer everything from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateQueueLabelUpdate Queue LabelA
Destructive
Inspect

Update a label's key, value, or color. Renaming key/value affects every case assigned to this label.

NameRequiredDescriptionDefault
keyNo
valueYes
label_idYesThe label's unique identifier
queue_idYesThe queue's unique identifier
color_hueNo

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is covered. The description adds real value beyond that by disclosing blast radius: renaming key/value mutates every case assigned to the label. It stops short of stating that updates are irreversible or what the response contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler, front-loading what can be changed and following immediately with the consequential side effect. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a five-parameter destructive mutation with no output schema, the description covers purpose and blast radius adequately. Gaps remain around required-vs-optional parameters and any permission requirements, but nothing essential to a correct call is missing.

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 coverage is only 40% (only queue_id and label_id are documented), so the description must compensate. It names the three mutable attributes (key, value, color_hue), which is helpful, but it never clarifies that value is required while key and color_hue are optional, nor the 0-360 range of the hue.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Update) and resource (label) plus the exact mutable fields (key, value, color), which is well beyond a restatement of the title. It does not, however, name or contrast itself with the obvious siblings createQueueLabel/deleteQueueLabel, so an agent must infer the create-vs-update-vs-delete split from naming alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance and no alternative tool is referenced. The warning about renaming affecting every assigned case is a side-effect disclosure rather than routing guidance, leaving the agent to infer that this is the tool for modifying an existing label.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateRevisionUpdate RevisionC
Destructive
Inspect

Update a revision's configuration, name, description, or handover targets. Returns the updated revision.

NameRequiredDescriptionDefault
configNoBuild configuration object
build_idYesThe build's unique identifier
handoverToNoThe single agent or code step to run after this one completes ("Handover to"). Null clears it; omit to leave it unchanged. Mutually exclusive with @-mention handovers in the AOP.
revision_nameNoOptional user-defined name for this revision. Pass null to clear.
handoverOptionsNoCode steps only. The targets the program may request, and whether it must. Null clears them; omit to leave unchanged. Mutually exclusive with handoverTo in one request.
handoverTargetIdsNoAgent IDs that this agent can hand over work to, used exactly as sent; an empty list clears them. Send null to use the agents the AOP mentions with <DUVO:AGENT> tags. Omit it to leave the targets as they are.
revision_descriptionNoOptional user-defined description for this revision. Pass null to clear.
selected_automation_revision_idNoThe automation revision this edit is being made at. Pass a draft and the edit is folded into that draft itself; pass the active revision and the edit lands on a draft branched from it. A historic revision is rejected — it cannot be activated from without an explicit rebase. A revision belonging to a different automation is ignored, and the edit targets the automation the addressed agent belongs to. Omit to target the automation's active revision.

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=false and readOnlyHint=false, so the mutation and risk profile are known; the description adds only that it returns the updated revision. It says nothing about what an update overwrites, that partial updates leave other fields untouched, or that a historic revision is rejected — all of which are behaviorally significant for a destructive call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, mutation scope front-loaded and the return value noted second. No filler, though the field enumeration is partly redundant with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter destructive mutator with nested objects and null/omit semantics, the description omits the partial-update model, the draft-vs-active-revision targeting behavior, and the mutual exclusivity of the handover parameters. The schema carries this, but the description should at least flag that omitting a field preserves it and that targeting a historic revision is rejected.

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% and each parameter carries rich documentation (null clears, omit leaves unchanged, handoverTo vs handoverOptions mutual exclusivity, selected_automation_revision_id branching rules). The description merely names the field groups, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource and enumerates the fields it can change (config, name, description, handover targets), which lets an agent distinguish it from createRevision or getRevision. It does not differentiate itself from adjacent mutators such as updateAutomation or updateSkillRevision, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no indication of when to prefer this tool over siblings, no preconditions (draft vs active revision, permissions), and no note that nothing changes if a field is omitted. Usage must be inferred entirely from the schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateScheduleUpdate ScheduleA
Destructive
Inspect

Update fields on an existing schedule. Only supplied fields are changed; omitted fields retain their current values. Owners may update their own schedules; team superadmins may update any schedule on agents in the current team. A schedule that belongs to an automation with revisions keeps firing as its automation's active revision says: a change to its timing is saved to the automation's draft and takes effect when the draft is made active (see pending_change), while enabled applies at once.

NameRequiredDescriptionDefault
dayNo
cronNo
timeNo
enabledNo
agent_idYesThe agent's unique identifier
timezoneNo
frequencyNo
recurringNo
schedule_idYesThe schedule's unique identifier
day_of_monthNo

TDQS

A3.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses the authorization model (owner vs team superadmin), the patch semantics of omitted fields, and the non-obvious split where timing changes land in an automation's draft while `enabled` applies immediately. That deferred-vs-immediate distinction is exactly the kind of behavior an agent could not infer from destructiveHint/idempotentHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core contract ('only supplied fields are changed') and structured as contract, permissions, then revision behavior. The final sentence is long and dense but carries genuinely load-bearing information, so little is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with annotations and no output schema, this covers what an agent needs to call it correctly: partial-update contract, permissions, and the draft/pending_change effect. Missing only return/confirmation details and any note on why destructiveHint is set.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 20% (agent_id, schedule_id), and the description only clarifies two optional fields in prose — 'timing' and 'enabled'. It says nothing about cron vs frequency vs day/time/day_of_month/recurring interrelationships, leaving most of the 10 parameters undocumented in both schema and description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Update fields on an existing schedule') and immediately pins down patch semantics, which distinguishes it from createSchedule/deleteSchedule. It does not explicitly name sibling tools, but the resource specificity makes the target unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied via the permission model (owners vs team superadmins) and the partial-update rule, so an agent knows when it is permitted and how omitted fields behave. However, there is no explicit when-to-use-this-vs-alternatives guidance, e.g. no pointer to createSchedule/deleteSchedule or a disable-only path.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateSecretUpdate SecretA
Destructive
Inspect

Update an env-var secret. Send values to replace all entries, or any of rename_keys, remove_keys, add_values for a non-destructive patch. Editing a team-shared secret or toggling sharing requires lead builder role.

NameRequiredDescriptionDefault
idYes
nameNo
sharedNo
valuesNo
add_valuesNo
remove_keysNo
rename_keysNo
service_slugNo

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, and the description adds genuinely useful context beyond them: it clarifies that `values` replaces all entries (the source of the destructive behavior) while the patch params are non-destructive, and it discloses the lead-builder role requirement for shared secrets. No contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with purpose, then the replace/patch distinction, then the auth constraint. Every clause carries information; nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with 0% schema coverage and no output schema, the description covers the risky parts (replace vs patch, role requirement) well enough to call safely. Gaps remain for `name` and `service_slug`, but the critical behavioral facts are present.

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 0%, so the description must carry parameter meaning. It does explain `values`, `rename_keys`, `remove_keys`, and `add_values` semantically (replace vs patch), and hints at `shared` via 'toggling sharing', but leaves `name` and `service_slug` unexplained across 8 parameters.

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?

States a specific verb and resource ('Update an env-var secret'), which cleanly separates it from createSecret, deleteSecret, getSecret, and listSecrets without the agent needing to open any schema. The scope is unambiguous.

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?

Explains the two invocation modes clearly: send `values` to replace everything, or use the patch params for a non-destructive update. It also flags the role prerequisite for shared-secret edits. It stops short of naming alternative tools for adjacent tasks, but the mode selection guidance is solid.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateSkillFileUpdate Skill FileA
DestructiveIdempotent
Inspect

Update the content of a file in a skill, overwriting the active revision in place — the previous content is not recoverable. Prefer the non-destructive flow when you can: createSkillRevision to open a draft, updateSkillRevisionFile to edit it, promoteSkillRevision to activate it. Only team skills can be edited.

NameRequiredDescriptionDefault
pathYesRelative path to the file inside the skill, e.g. SKILL.md.
contentYesNew UTF-8 text content for the file.
skill_idYesSkill ID.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, but the description adds the consequence that annotations cannot express: the previous content is not recoverable because the active revision is overwritten in place. It also adds a permission constraint (team skills only) beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, zero filler: the destructive consequence comes first, then the safer alternative path, then the eligibility constraint. Each sentence earns its place.

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?

No output schema is needed for a mutation whose effect is fully described; the description covers destructiveness, reversibility, the preferred alternative workflow, and the permission scope. Nothing an agent needs before calling it is missing.

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% across all three parameters (path, content, skill_id), so the schema already carries parameter meaning. The description adds no syntax, format, or constraint detail beyond it, making the baseline 3 appropriate.

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?

States a specific verb (update) and resource (content of a file in a skill) plus the exact effect ('overwriting the active revision in place'). This clearly separates it from near-neighbors like updateSkillRevisionFile, getSkillFileContent, and updateFileContent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to an alternative non-destructive flow and names the exact three tools that compose it (createSkillRevision, updateSkillRevisionFile, promoteSkillRevision), plus a hard precondition ('Only team skills can be edited'). Both when-to-use and when-not are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateSkillRevisionUpdate Skill RevisionA
Destructive
Inspect

Rename a skill revision or change its description. Works for drafts, the active revision, and historic revisions.

NameRequiredDescriptionDefault
revision_nameNoOptional user-defined name for this revision. Pass null to clear.
skill_revision_idYesSkill revision ID.
revision_descriptionNoOptional user-defined description for this revision. Pass null to clear.

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, so the safety profile is carried by structured data. The description adds the useful scope note that all revision states are editable, but does not disclose consequences (e.g., that null clears a field) or confirm reversibility. Adequate with annotations doing most of the work.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences with no filler, and the core action is front-loaded before the scope qualifier. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple 3-parameter mutation with full schema coverage, no output schema, and annotations covering the safety profile, the description is close to sufficient. It would be fully complete with a note on whether edits apply immediately or require a promote/publish step.

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 schema already documents the id, the optional name, and the optional description including the "pass null to clear" behavior. The description adds no parameter-level meaning beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: renaming or changing the description of a skill revision. This is unambiguous and distinguishable from createSkillRevision, deleteSkillRevision, and updateSkillRevisionFile. It does not explicitly name a sibling to route against, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Works for drafts, the active revision, and historic revisions" gives useful scope on which revisions can be targeted, which is real guidance. However, it does not say when to use this versus alternatives such as updateSkillRevisionFile or promoteSkillRevision, so usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateSkillRevisionFileUpdate Skill Revision FileA
DestructiveIdempotent
Inspect

Write a text file into a skill revision. Writing into a draft leaves the active revision untouched until the draft is promoted; writing into the active revision changes what the skill runs immediately. Historic revisions are read-only: create a draft from one to edit it.

NameRequiredDescriptionDefault
pathYesRelative path to the file inside the revision, e.g. SKILL.md.
contentYesNew UTF-8 text content for the file.
skill_revision_idYesSkill revision ID.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (write, destructive, idempotent), the description adds valuable behavioral context: the draft-versus-active distinction, the impact on the running skill, and the read-only constraint on historic revisions. This meaningfully explains side effects the annotations alone do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each carrying essential information. The main action is front-loaded, followed by the critical revision-state semantics and the read-only caveat. No filler or redundant restating of the schema.

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?

The description fully covers the most important contextual complexity of this tool: how revisions behave differently depending on draft/active/historic state. With no output schema, return values need not be described, and the 100% parameter coverage handles the remaining specifics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the parameters are already documented. The description adds extra semantic value by implying that skill_revision_id must refer to a draft or active revision (not historic), and by framing path and content as file contents within a revision.

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 states a specific verb and resource: 'Write a text file into a skill revision.' It clearly distinguishes this file-level operation from sibling tools like updateSkillFile and updateSkillRevision by targeting files within a revision and explaining draft/active/historic behavior.

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?

The description gives clear context for when to use the tool: writing to a draft leaves the active revision untouched, while writing to the active revision changes behavior immediately. It also tells users that historic revisions are read-only and advises creating a draft to edit them, but it does not name the specific alternative tool to use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateSlackTriggerUpdate Slack Channel TriggerA
Destructive
Inspect

Update a Slack channel trigger you own — repoint it at another channel, change which messages match, or pause and resume it with enabled. Only the supplied fields change. Resuming a paused trigger requires the Slack connection it runs off to still be available on the agent; changing the channel resets the trigger's seen-message state.

NameRequiredDescriptionDefault
enabledNoSet to false to pause the trigger without deleting it, or true to resume it. Resuming requires the connection the trigger uses to still be available on the agent.
channel_idNoNew Slack channel ID to watch. Omit to leave unchanged.
is_privateNoWhether the channel is private.
match_ruleNoWhich channel messages fire the trigger: `{"kind":"all"}` for every message, or `{"kind":"contains","values":["invoice"]}` to match keywords.
trigger_idYesThe Slack channel trigger's unique identifier
channel_nameNoNew Slack channel name, without the leading `#`.

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true and idempotentHint=false, and the description adds real value beyond them: partial-update semantics ('Only the supplied fields change'), the resume prerequisite (the Slack connection must still be available on the agent), and the destructive consequence that changing the channel resets the trigger's seen-message state. These are meaningful behavioral disclosures the annotations alone do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action is front-loaded in the first sentence, and the following sentences each add distinct value (partial-update semantics, resume prerequisite, state reset). No filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation tool with no output schema, the description covers the key risks: partial updates, the resume prerequisite, and the seen-state reset. It is nearly complete, though it omits any note on what the tool returns or confirmation/irreversibility details.

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 schema already documents every parameter (enabled, channel_id, channel_name, match_rule, is_private, trigger_id) in detail. The description mentions enabled and the channel concept but adds no syntax or format detail beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Update) and resource (Slack channel trigger) plus the ownership scope, and enumerates the three mutable aspects (channel, match rule, enabled). It is clearly a partial-update tool, though it does not name the sibling alternatives like createAgentSlackTrigger or deleteSlackTrigger to distinguish itself explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the enumerated actions — repoint, change matching, pause/resume — and the ownership qualifier ('you own') hints at a constraint. However, it never states when to prefer this over deleteSlackTrigger (removal) or createAgentSlackTrigger (creation), so an agent must infer the boundary itself.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateTeamInviteUpdate Team InviteA
Destructive
Inspect

Change the role on a pending team invitation. Only pending invitations can be updated — one already accepted or declined is rejected. Requires the Manager role or above on the invitation's own team.

NameRequiredDescriptionDefault
idYesID of the pending invitation to update.
roleYesNew team role for the invitation. One of: team:owner, team:superadmin, team:admin (deprecated), team:manager, team:builder, team:member, team:clarity-member. You cannot assign a role above your own.
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=false, openWorldHint=false), so the burden is lower. The description adds genuinely new behavioral context: state gating on pending status and the required permission level on the invitation's team. It does not explain whether changing the role re-sends the invitation email or re-notifies the invitee, which matters for a true mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the action, then the state constraint, then the permission requirement. No filler and nothing an agent must read past to reach the operative rule.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description does not need to explain a return value for a simple role mutation. Combined with 100%-covered annotations and schema, the gaps are minor: the effect on the invitee (re-notification/resend) is unstated, and no alternative tool is offered for non-pending invitations.

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%: the role enum, the id format, and the team_id API-key-vs-OAuth fallback behavior are all documented in the schema. The description adds no parameter-level detail (e.g., allowed role values or the 'cannot assign above your own role' rule), so the baseline 3 is appropriate.

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?

Opens with a precise verb+resource+scope: 'Change the role on a pending team invitation.' This cleanly separates it from sibling mutators like updateTeamMemberRole (existing members), createTeamInvite, and deleteTeamInvite without requiring the schema to be opened.

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?

Gives both a precondition ('Only pending invitations can be updated — one already accepted or declined is rejected') and an authorization gate ('Requires the Manager role or above on the invitation's own team'), which is strong when-to-use guidance. It stops short of naming an alternative tool for the accepted-invitation case (e.g., updateTeamMemberRole), so it is not a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

updateTeamMemberRoleUpdate Team Member RoleA
Destructive
Inspect

Update an existing team member's role. Requires the Manager role or above; only an Owner may grant or remove the Owner role, and the last remaining Owner cannot be demoted. A member whose Owner role is inherited from the organization cannot be changed here.

NameRequiredDescriptionDefault
roleYes
team_idNoDuvo team UUID to operate on. API keys are pinned to a single team — omit this (it falls back to the key's team) or pass that same team; a different team is rejected. OAuth callers, who can span multiple teams, should pass the target team here.
memberIdYesMember (user) ID

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false, but the description adds non-obvious behavioral constraints that structured data cannot convey: the last remaining Owner cannot be demoted, and organization-inherited Owner roles cannot be changed here. These are exactly the guardrails an agent needs before attempting a mutation. It stops short of describing what the operation returns or how failures surface.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose in the first clause, then layers constraints in a compact sequence. Every clause carries information (permissions, edge cases) with no filler. It is dense but readable; the role-value ambiguity noted elsewhere is an omission rather than verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive mutation, the description covers permissions, the two most likely failure conditions, and the inheritance exception, on top of annotations that flag the operation as destructive and non-idempotent. With no output schema it need not explain returns. The remaining gap is the undocumented 'role' value set, which the description alludes to but never specifies.

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 coverage is 67%, with the key parameter 'role' carrying no description and no enum. The description only incidentally hints at valid values ('Manager role', 'Owner role'), which partially compensates but does not enumerate what the agent must pass. The documented memberId/team_id parameters add no description-side value beyond the schema.

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?

States a specific verb+resource ('Update an existing team member's role') that unambiguously identifies the operation. It is clearly distinguishable from the nearest sibling, removeTeamMember, and no other sibling performs member-role mutation. An agent can select this correctly without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description supplies real prerequisites ('Requires the Manager role or above', Owner-only rules), which is useful usage context. However, it never states when to use this tool versus alternatives (e.g. removeTeamMember, inviteOrgMember), and gives no when-not guidance beyond the two edge cases. Usage is implied through permissions rather than routed explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

upgradeClarityProcessUpgrade Clarity ProcessA
Destructive
Inspect

Move a v1 clarity process into v2. Rows with generated analysis are reset in place and regenerated; rows without analysis migrate in place when not generating.

NameRequiredDescriptionDefault
idYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, readOnlyHint=false, and idempotentHint=false, but the description adds substantive row-level behavior beyond them: rows with generated analysis are reset in place and regenerated, rows without analysis migrate in place when not generating. This tells the agent data can be destroyed or rewritten. It stops short of stating reversibility/rollback or permission requirements, which would be the final piece for a destructive migration.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, purpose front-loaded before the row-behavior detail, with no filler. The second sentence is dense and uses unexplained terms ('rows', 'when not generating') that slightly reduce clarity, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter destructive mutation with no output schema and annotations covering the safety profile, the description supplies purpose plus meaningful migration behavior. Remaining gaps are irreversibility/rollback semantics and any auth or v1-precondition requirements.

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 0% and the single 'id' parameter carries no schema description, so the description should compensate. It does not mention the parameter at all or clarify that id must be a v1 process id. With only one reasonably inferable parameter, this is a moderate rather than severe gap.

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?

States a specific verb and resource ('Move a v1 clarity process into v2') with a clear version-transition scope. The v1→v2 migration semantics distinguish it semantically from updateClarityProcess (in-place edits) and getLegacyClarityProcess (read of legacy). An agent can identify this as the migration tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the trigger condition (a v1 process that needs to move to v2), which is real usage context, but never states it explicitly as 'use when...' and names no alternative or exclusion. No guidance on prerequisites (e.g., that the id must reference a legacy v1 process). Implied usage only.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

uploadSandboxFileUpload Sandbox FileAInspect

Upload a file directly to the sandbox. Maximum file size is 10MB. For larger files, use POST /v2/sandboxes/:sandbox_id/upload-urls.

NameRequiredDescriptionDefault
sandbox_idYesThe sandbox's unique identifier

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description reveals a key behavioral constraint—the 10MB file size limit—and directs users to the appropriate fallback when that limit is exceeded. While it lacks details on success responses, failure modes (e.g., duplicate names), or overwrite behavior, the annotations (readOnlyHint: false, destructiveHint: false) already cover the read/write and destructive nature. The description adds meaningful behavioral context beyond the annotations, meriting a high score.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is exceptionally concise—two sentences—with the action stated first and the size constraint and fallback immediately following. Every word contributes value; there is no padding or redundancy. The front-loaded structure makes the critical information immediately accessible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one declared parameter, no output schema, no nested objects), the description is highly complete. It covers the primary action, the size threshold, and the alternative flow. The only missing element is the mechanism for providing the file content itself, but since the API endpoint is implied and the agent has sibling tools like createSandboxUploadUrl for context, the description adequately serves its purpose for most scenarios.

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?

The schema fully documents the sandbox_id parameter with a clear description, achieving 100% coverage of declared inputs. The description adds the file size context (10MB) but fails to address a critical undisclosed parameter: how the actual file content is transmitted (e.g., request body, multipart form-data). Since the schema only lists sandbox_id, an agent would be left guessing how to attach the file, preventing the description from fully compensating for this gap. The baseline of 3 is appropriate.

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 clearly states the exact action ('Upload a file directly to the sandbox'), identifying the specific verb (Upload), resource (file), and target (sandbox). It also distinguishes itself from sibling tools by explicitly defining a size limit (10MB) and referencing the alternate URL-based upload path, making its purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool (for files up to 10MB) and when not to use it ('For larger files, use POST /v2/sandboxes/:sandbox_id/upload-urls'), providing a direct alternative. This gives the agent clear conditional logic for tool selection without needing to infer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

upsertAgentTriggerUpsert Agent TriggerA
DestructiveIdempotent
Inspect

Create or update the authenticated user's trigger for an integration on an agent. The integration must already be connected to the agent (its OAuth connection set up in the Duvo dashboard). Set enabled: false to pause a trigger without deleting it. An agent holds one trigger per integration for a user, so a save with a different trigger_type replaces the existing one — except when that trigger is an @mention trigger, which is managed from the agent's mention setting and answers 409 (mention_trigger_protected) here. @mention triggers are best managed from that setting throughout: this route leaves an existing one's filter_config untouched, and refuses to create a teams_mention trigger without a filter_config.tenantId (400, mention_trigger_workspace_required) — a Slack mention trigger has no equivalent field to supply.

NameRequiredDescriptionDefault
agentIdYesThe agent's unique identifier
enabledNoWhether the trigger is active. Defaults to true.
trigger_typeYesTrigger type within the integration (e.g. `email_received`). Discover valid values via the trigger types endpoint. Integrations that enumerate their trigger types (Microsoft Teams, Google Drive, Google Sheets) reject anything else with 400 (`trigger_type_unsupported`), except a save that pauses a trigger already carrying that type.
filter_configNoIntegration-specific filter config (e.g. sender/subject filters). Shape comes from the integration's filter schema. Replaces the trigger's current config, so send the whole object — except on an @mention trigger, whose config is managed from the agent's mention setting and is left as it is.
integration_slugYesIntegration slug the trigger fires for (e.g. `gmail`, `outlook`, `linear-native`, `google-drive`).

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare the safety profile (destructive, idempotent, non-read-only). The description adds substantial behavior the annotations cannot: replacement semantics when trigger_type changes, 409 mention_trigger_protected, 400 mention_trigger_workspace_required, 400 trigger_type_unsupported, and the fact that an existing @mention trigger's filter_config is left untouched rather than overwritten.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, and the dense error-code/edge-case detail that follows is information-dense rather than filler. It is long, but every clause carries a distinct operative rule, so only mild trimming is possible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter upsert with nested objects, no output schema and annotation-covered safety, the description covers prerequisites, replacement semantics, protected-resource behavior and three distinct error codes. It never says what the response contains (the resulting trigger object), which is the one remaining gap for an agent verifying success.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema coverage the baseline is 3, and the description earns an extra point: it explains that enabled:false pauses without deleting, that filter_config is replaced wholesale, and that teams_mention requires a filter_config.tenantId while Slack has no equivalent field. Some of this (whole-object replacement) is also in the schema, so it is not entirely additive.

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 first sentence gives a precise verb pair (create or update) and resource (the authenticated user's trigger for an integration on an agent), and the upsert scope is immediately evident. An agent can tell this apart from the specialized createAgentSlackTrigger/createAgentCaseTrigger variants and from deleteAgentTrigger without opening any schema.

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 states a real prerequisite (the integration must already be connected via OAuth in the dashboard) and a routing recommendation (@mention triggers should be managed from the agent's mention setting throughout). It stops short of naming the alternative tools (e.g. listAgentTriggerTypes to discover valid values) explicitly, so the agent must infer the siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 6 tool updates
    • ChangedcreateRevision4 fields changed
      • addedInput schema / properties / handover_target_ids / anyOf
        Added value: +[
        +  {
        +    "items": {
        +      "format": "uuid",
        +      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / handover_target_ids / description
        Previous value: -"Agent IDs that this agent can hand work off to. Omit to inherit the source build's targets when the AOP has no agent mentions and handover_to is not sent; an empty list clears them."New value: +"Agent IDs that this agent can hand work off to, used exactly as sent; an empty list means none. Send null or omit it to use the agents the AOP mentions with <DUVO:AGENT> tags. Targets are never copied from the source build."
      • removedInput schema / properties / handover_target_ids / items
        Removed value: -{
        -  "format": "uuid",
        -  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -  "type": "string"
        -}
      • removedInput schema / properties / handover_target_ids / type
        Removed value: -"array"
    • ChangedgetNotificationBatch1 field changed
      • changedInput schema / properties / type / enum
        Previous value: -[
        -  "connection_broken",
        -  "case_failed",
        -  "critical_case_issue",
        -  "case_issue",
        -  "critical_eval_issue",
        -  "eval_issue",
        -  "job_issue",
        -  "job_done",
        -  "background_job",
        -  "schedule_issue",
        -  "config_proposal"
        -]New value: +[
        +  "connection_broken",
        +  "login_broken",
        +  "case_failed",
        +  "critical_case_issue",
        +  "case_issue",
        +  "critical_eval_issue",
        +  "eval_issue",
        +  "job_issue",
        +  "job_done",
        +  "background_job",
        +  "schedule_issue",
        +  "config_proposal",
        +  "routine_candidate"
        +]
    • ChangedgetNotificationFeed1 field changed
      • changedInput schema / properties / type / enum
        Previous value: -[
        -  "connection_broken",
        -  "case_failed",
        -  "critical_case_issue",
        -  "case_issue",
        -  "critical_eval_issue",
        -  "eval_issue",
        -  "job_issue",
        -  "job_done",
        -  "background_job",
        -  "schedule_issue",
        -  "config_proposal"
        -]New value: +[
        +  "connection_broken",
        +  "login_broken",
        +  "case_failed",
        +  "critical_case_issue",
        +  "case_issue",
        +  "critical_eval_issue",
        +  "eval_issue",
        +  "job_issue",
        +  "job_done",
        +  "background_job",
        +  "schedule_issue",
        +  "config_proposal",
        +  "routine_candidate"
        +]
    • ChangedlistNotifications2 fields changed
      • changedInput schema / properties / type / description
        Previous value: -"Only return notifications of this type. One of: connection_broken, case_failed, critical_case_issue, case_issue, critical_eval_issue, eval_issue, job_issue, job_done, background_job, schedule_issue, config_proposal."New value: +"Only return notifications of this type. One of: connection_broken, login_broken, case_failed, critical_case_issue, case_issue, critical_eval_issue, eval_issue, job_issue, job_done, background_job, schedule_issue, config_proposal, routine_candidate."
      • changedInput schema / properties / type / enum
        Previous value: -[
        -  "connection_broken",
        -  "case_failed",
        -  "critical_case_issue",
        -  "case_issue",
        -  "critical_eval_issue",
        -  "eval_issue",
        -  "job_issue",
        -  "job_done",
        -  "background_job",
        -  "schedule_issue",
        -  "config_proposal"
        -]New value: +[
        +  "connection_broken",
        +  "login_broken",
        +  "case_failed",
        +  "critical_case_issue",
        +  "case_issue",
        +  "critical_eval_issue",
        +  "eval_issue",
        +  "job_issue",
        +  "job_done",
        +  "background_job",
        +  "schedule_issue",
        +  "config_proposal",
        +  "routine_candidate"
        +]
    • ChangedmarkNotificationBatchRead2 fields changed
      • changedInput schema / properties / types / items / enum
        Previous value: -[
        -  "connection_broken",
        -  "case_failed",
        -  "critical_case_issue",
        -  "case_issue",
        -  "critical_eval_issue",
        -  "eval_issue",
        -  "job_issue",
        -  "job_done",
        -  "background_job",
        -  "schedule_issue",
        -  "config_proposal"
        -]New value: +[
        +  "connection_broken",
        +  "login_broken",
        +  "case_failed",
        +  "critical_case_issue",
        +  "case_issue",
        +  "critical_eval_issue",
        +  "eval_issue",
        +  "job_issue",
        +  "job_done",
        +  "background_job",
        +  "schedule_issue",
        +  "config_proposal",
        +  "routine_candidate"
        +]
      • changedInput schema / properties / types / maxItems
        Previous value: -11New value: +13
    • ChangedupdateRevision4 fields changed
      • addedInput schema / properties / handoverTargetIds / anyOf
        Added value: +[
        +  {
        +    "items": {
        +      "format": "uuid",
        +      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • changedInput schema / properties / handoverTargetIds / description
        Previous value: -"Agent IDs that this agent can hand over work to"New value: +"Agent IDs that this agent can hand over work to, used exactly as sent; an empty list clears them. Send null to use the agents the AOP mentions with <DUVO:AGENT> tags. Omit it to leave the targets as they are."
      • removedInput schema / properties / handoverTargetIds / items
        Removed value: -{
        -  "format": "uuid",
        -  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -  "type": "string"
        -}
      • removedInput schema / properties / handoverTargetIds / type
        Removed value: -"array"
  2. 9 tool updates
    • RemovedanalyzeClarityProcessConflicts
    • RemovedattachQueueJsonSchema
    • RemovedcreateQueueJsonSchema
    • RemoveddetachQueueJsonSchema
    • RemovedgetQueueJsonSchema
    • RemovedlistClarityProcessConflicts
    • RemovedreplaceQueueJsonSchema
    • RemovedupdateQueueJsonSchemaSettings
    • RemovedupdateSkillAskDuvo
  3. 2 tool updates
    • AddedanalyzeClarityProcessConflicts
    • AddedlistClarityProcessConflicts
  4. 3 tool updates
    • AddedapproveAutomationProposal
    • AddedgenerateAutomationProcessMap
    • AddedgenerateAutomationProposal
  5. 3 tool updates
    • RemovedconnectPulseDataSource
    • RemoveddisconnectPulseDataSource
    • RemovedlistPulseDataSources
  6. 8 tool updates
    • RemovedacceptClarityCaptureSuggestion
    • RemovedassignClarityLandscapeCaptureRequest
    • ChangedcreateAgent2 fields changed
      • changedInput schema / properties / build / properties / config / properties / data / properties / models / properties / agent / properties / model / enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4.1-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max",
        -  "deepseek-v4-flash"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4.1-flash",
        +  "deepseek-v4.1-flash-1017",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max",
        +  "deepseek-v4-flash"
        +]
      • changedInput schema / properties / build / properties / config / properties / data / properties / models / properties / agent / properties / model / x-extensible-enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4.1-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max",
        -  "deepseek-v4-flash"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4.1-flash",
        +  "deepseek-v4.1-flash-1017",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max",
        +  "deepseek-v4-flash"
        +]
    • ChangedcreateAutomation2 fields changed
      • changedInput schema / properties / first_agent / properties / config / properties / data / properties / models / properties / agent / properties / model / enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4.1-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max",
        -  "deepseek-v4-flash"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4.1-flash",
        +  "deepseek-v4.1-flash-1017",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max",
        +  "deepseek-v4-flash"
        +]
      • changedInput schema / properties / first_agent / properties / config / properties / data / properties / models / properties / agent / properties / model / x-extensible-enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4.1-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max",
        -  "deepseek-v4-flash"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4.1-flash",
        +  "deepseek-v4.1-flash-1017",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max",
        +  "deepseek-v4-flash"
        +]
    • ChangedcreateClarityLandscapeNode1 field changed
      • changedInput schema / properties / creationMode / description
        Previous value: -"Use \"proposal\" to add an area for review instead of asserting it exists. A proposal is idempotent: an equivalent live area under the same parent is returned untouched rather than duplicated. Defaults to \"active\" — except in a landscape-onboarding chat, which may only propose, and so defaults to \"proposal\"."New value: +"Use \"proposal\" to add an area for review instead of asserting it exists. A proposal is idempotent: an equivalent live area under the same parent is returned untouched rather than duplicated. Defaults to \"active\"."
    • ChangedcreateRevision1 field changed
      • changedInput schema / properties / config / anyOf
        Previous value: -[
        -  {
        -    "properties": {
        -      "data": {
        -        "description": "Agent configuration payload",
        -        "properties": {
        -          "files": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Team files that should be available to the agent, each given as the relative file path returned in the `path` field of `GET /v2/teams/{teamId}/files` (for example `report.md` or `folder/doc.md`) — not the `id` field, which is a GCS object identifier."
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "items": {
        -                  "properties": {
        -                    "content": {
        -                      "anyOf": [
        -                        {
        -                          "type": "string"
        -                        },
        -                        {
        -                          "items": {
        -                            "anyOf": [
        -                              {
        -                                "properties": {
        -                                  "text": {
        -                                    "type": "string"
        -                                  },
        -                                  "type": {
        -                                    "const": "input_text",
        -                                    "type": "string"
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type",
        -                                  "text"
        -                                ],
        -                                "type": "object"
        -                              },
        -                              {
        -                                "properties": {
        -                                  "detail": {
        -                                    "anyOf": [
        -                                      {
        -                                        "enum": [
        -                                          "low",
        -                                          "high",
        -                                          "auto"
        -                                        ],
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  },
        -                                  "file_id": {
        -                                    "anyOf": [
        -                                      {
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  },
        -                                  "type": {
        -                                    "const": "input_image",
        -                                    "type": "string"
        -                                  },
        -                                  "url": {
        -                                    "anyOf": [
        -                                      {
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type"
        -                                ],
        -                                "type": "object"
        -                              },
        -                              {
        -                                "properties": {
        -                                  "file_id": {
        -                                    "type": "string"
        -                                  },
        -                                  "type": {
        -                                    "const": "input_file",
        -                                    "type": "string"
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type",
        -                                  "file_id"
        -                                ],
        -                                "type": "object"
        -                              }
        -                            ]
        -                          },
        -                          "type": "array"
        -                        }
        -                      ]
        -                    },
        -                    "role": {
        -                      "enum": [
        -                        "system",
        -                        "user",
        -                        "assistant"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    "type": {
        -                      "anyOf": [
        -                        {
        -                          "const": "message",
        -                          "type": "string"
        -                        },
        -                        {
        -                          "type": "null"
        -                        }
        -                      ]
        -                    }
        -                  },
        -                  "required": [
        -                    "role",
        -                    "content"
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              }
        -            ],
        -            "description": "Initial agent instructions — either a single system prompt string or a list of structured messages"
        -          },
        -          "models": {
        -            "description": "Model configuration for each capability the agent uses",
        -            "properties": {
        -              "agent": {
        -                "description": "Primary agent model configuration",
        -                "properties": {
        -                  "model": {
        -                    "description": "Model identifier used for the primary agent loop (Claude, or an OSS model when the team's oss_models flag — or oss_models_public for the public subset — is enabled)",
        -                    "enum": [
        -                      "claude-haiku-4-5-20251001",
        -                      "claude-haiku-5-5",
        -                      "claude-haiku-5-5[1m]",
        -                      "claude-sonnet-5",
        -                      "claude-sonnet-5[1m]",
        -                      "claude-sonnet-5-5",
        -                      "claude-sonnet-5-5[1m]",
        -                      "claude-opus-5",
        -                      "claude-opus-5[1m]",
        -                      "claude-opus-5-5",
        -                      "claude-opus-5-5[1m]",
        -                      "kimi-k3",
        -                      "kimi-k3-duvo",
        -                      "glm-5.3-flash",
        -                      "deepseek-v4.1-flash",
        -                      "minimax-m3",
        -                      "d1-max",
        -                      "duvo-1-max",
        -                      "duvo-1-max-sonnet-1m",
        -                      "duvo-1-max-sonnet-4.5",
        -                      "duvo-1-max-sonnet-4.5-1m",
        -                      "duvo-1-max-opus",
        -                      "duvo-1-max-opus-4.5",
        -                      "gpt-4.1",
        -                      "gpt-4o",
        -                      "gpt-4o-mini",
        -                      "gpt-5",
        -                      "gpt-5.1",
        -                      "claude-sonnet-4-20250514",
        -                      "claude-sonnet-4-20250514[1m]",
        -                      "claude-sonnet-4-5-20250929",
        -                      "claude-sonnet-4-5-20250929[1m]",
        -                      "claude-sonnet-4-6",
        -                      "claude-sonnet-4-6[1m]",
        -                      "claude-opus-4-1-20250805",
        -                      "claude-opus-4-5-20251101",
        -                      "claude-opus-4-6",
        -                      "claude-opus-4-6[1m]",
        -                      "claude-opus-4-7",
        -                      "claude-opus-4-7[1m]",
        -                      "claude-opus-4-8",
        -                      "claude-opus-4-8[1m]",
        -                      "glm-5.2",
        -                      "qwen3.6-27b",
        -                      "qwen3.8-max",
        -                      "deepseek-v4-flash"
        -                    ],
        -                    "type": "string",
        -                    "x-extensible-enum": [
        -                      "claude-haiku-4-5-20251001",
        -                      "claude-haiku-5-5",
        -                      "claude-haiku-5-5[1m]",
        -                      "claude-sonnet-5",
        -                      "claude-sonnet-5[1m]",
        -                      "claude-sonnet-5-5",
        -                      "claude-sonnet-5-5[1m]",
        -                      "claude-opus-5",
        -                      "claude-opus-5[1m]",
        -                      "claude-opus-5-5",
        -                      "claude-opus-5-5[1m]",
        -                      "kimi-k3",
        -                      "kimi-k3-duvo",
        -                      "glm-5.3-flash",
        -                      "deepseek-v4.1-flash",
        -                      "minimax-m3",
        -                      "d1-max",
        -                      "duvo-1-max",
        -                      "duvo-1-max-sonnet-1m",
        -                      "duvo-1-max-sonnet-4.5",
        -                      "duvo-1-max-sonnet-4.5-1m",
        -                      "duvo-1-max-opus",
        -                      "duvo-1-max-opus-4.5",
        -                      "gpt-4.1",
        -                      "gpt-4o",
        -                      "gpt-4o-mini",
        -                      "gpt-5",
        -                      "gpt-5.1",
        -                      "claude-sonnet-4-20250514",
        -                      "claude-sonnet-4-20250514[1m]",
        -                      "claude-sonnet-4-5-20250929",
        -                      "claude-sonnet-4-5-20250929[1m]",
        -                      "claude-sonnet-4-6",
        -                      "claude-sonnet-4-6[1m]",
        -                      "claude-opus-4-1-20250805",
        -                      "claude-opus-4-5-20251101",
        -                      "claude-opus-4-6",
        -                      "claude-opus-4-6[1m]",
        -                      "claude-opus-4-7",
        -                      "claude-opus-4-7[1m]",
        -                      "claude-opus-4-8",
        -                      "claude-opus-4-8[1m]",
        -                      "glm-5.2",
        -                      "qwen3.6-27b",
        -                      "qwen3.8-max",
        -                      "deepseek-v4-flash"
        -                    ]
        -                  }
        -                },
        -                "required": [
        -                  "model"
        -                ],
        -                "type": "object"
        -              },
        -              "browsing": {
        -                "description": "Browsing/computer-use model configuration",
        -                "properties": {
        -                  "model": {
        -                    "description": "Model identifier for the browsing provider",
        -                    "enum": [
        -                      "gemini-2.5-pro",
        -                      "gemini-2.5-flash",
        -                      "gemini-3-pro-preview",
        -                      "claude-haiku-4-5",
        -                      "claude-sonnet-4-5",
        -                      "claude-opus-4-1"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "provider": {
        -                    "description": "Provider backing the browsing/computer-use model",
        -                    "enum": [
        -                      "google",
        -                      "anthropic"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "provider",
        -                  "model"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "agent",
        -              "browsing"
        -            ],
        -            "type": "object"
        -          },
        -          "options": {
        -            "additionalProperties": {},
        -            "description": "Optional runtime options controlling how the agent executes",
        -            "properties": {
        -              "benchmarkExpectedOutcomes": {
        -                "description": "Expected outcomes used when running benchmark scenarios",
        -                "items": {
        -                  "properties": {
        -                    "criteria": {
        -                      "description": "Pass/fail criteria used to evaluate the outcome",
        -                      "type": "string"
        -                    },
        -                    "description": {
        -                      "description": "Human-readable description of the expected outcome",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "description",
        -                    "criteria"
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "browserProvider": {
        -                "description": "Browser infrastructure provider",
        -                "enum": [
        -                  "browserbase",
        -                  "browser-use"
        -                ],
        -                "type": "string"
        -              },
        -              "evaluationSchemaId": {
        -                "description": "ID of the evaluation schema to apply to runs of this agent",
        -                "type": "string"
        -              },
        -              "supervisedMode": {
        -                "description": "Run the agent under Duvo's permission classifier: every tool call is classified as allow/deny/ask, with 'ask' routed to human-in-the-loop approval. Mutually exclusive with browsing and computer-use connections.",
        -                "type": "boolean"
        -              }
        -            },
        -            "type": "object"
        -          },
        -          "plugins": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Plugins to load — either a built-in plugin name (e.g. \"code-review\") or a GitHub URL (e.g. \"https://github.com/owner/repo\")"
        -          },
        -          "skills": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "IDs of skills (team or system) that should be available to the agent"
        -          },
        -          "subAgents": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Retired — Sub-Assignments was removed. Accepted for backwards compatibility and ignored."
        -          }
        -        },
        -        "required": [
        -          "models",
        -          "input"
        -        ],
        -        "type": "object"
        -      },
        -      "version": {
        -        "const": "v2",
        -        "description": "Schema version discriminator — must be \"v2\" for the current schema",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "version",
        -      "data"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "properties": {
        -      "data": {
        -        "description": "Code step configuration payload",
        -        "properties": {
        -          "files": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Team file paths this step can read at run time"
        -          },
        -          "handoverRequired": {
        -            "default": false,
        -            "description": "When the step declares handover options, whether a run that exits cleanly without requesting one fails. Ignored when the step declares no options.",
        -            "type": "boolean"
        -          },
        -          "language": {
        -            "description": "Language the step's program is written in",
        -            "enum": [
        -              "python"
        -            ],
        -            "type": "string"
        -          },
        -          "maxConcurrency": {
        -            "description": "Most runs of this step that may be in flight at once on one queue, on top of the queue's own concurrency. Absent means only the queue's limit applies. Every claim enforces it; only cases handed to the step (handover, postpone, reprocess) are also kept out of the queue's free slots while the step is full. Cases a trigger or a revision route sends straight to a capped step can still take queue slots and wait there, delaying other steps on the same queue.",
        -            "exclusiveMinimum": 0,
        -            "maximum": 1000,
        -            "type": "integer"
        -          },
        -          "source": {
        -            "description": "Where the step's program comes from",
        -            "oneOf": [
        -              {
        -                "properties": {
        -                  "code": {
        -                    "description": "Program held in the build config. Written to `main.py` and run with `python main.py`.",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "kind": {
        -                    "const": "inline",
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "kind",
        -                  "code"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "properties": {
        -                  "bundle": {
        -                    "description": "The program's files, as a content-addressed manifest",
        -                    "properties": {
        -                      "bucket": {
        -                        "description": "GCS bucket the bundle's blobs are stored in",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "files": {
        -                        "description": "The program's files, one manifest entry each",
        -                        "items": {
        -                          "properties": {
        -                            "path": {
        -                              "description": "Path the file is materialised at, relative to the work dir",
        -                              "minLength": 1,
        -                              "type": "string"
        -                            },
        -                            "sha256": {
        -                              "description": "Digest of the file's bytes, and the key its blob is stored at",
        -                              "maxLength": 64,
        -                              "minLength": 64,
        -                              "pattern": "^[0-9a-f]{64}$",
        -                              "type": "string"
        -                            },
        -                            "sizeBytes": {
        -                              "description": "UTF-8 byte length of the file's contents",
        -                              "maximum": 131072,
        -                              "minimum": 0,
        -                              "type": "integer"
        -                            }
        -                          },
        -                          "required": [
        -                            "path",
        -                            "sha256",
        -                            "sizeBytes"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "maxItems": 200,
        -                        "type": "array"
        -                      }
        -                    },
        -                    "required": [
        -                      "bucket",
        -                      "files"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "kind": {
        -                    "const": "files",
        -                    "type": "string"
        -                  },
        -                  "startCommand": {
        -                    "description": "Command run from the root of the step's file system, e.g. \"python main.py\".",
        -                    "maxLength": 2000,
        -                    "minLength": 1,
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "kind",
        -                  "startCommand"
        -                ],
        -                "type": "object"
        -              }
        -            ]
        -          },
        -          "timeoutMs": {
        -            "default": 600000,
        -            "description": "Wall-clock budget for one execution of the step",
        -            "exclusiveMinimum": 0,
        -            "maximum": 3600000,
        -            "type": "integer"
        -          }
        -        },
        -        "required": [
        -          "language",
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "version": {
        -        "const": "v1",
        -        "description": "Schema version discriminator — must be \"v1\" for the current code-step schema",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "version",
        -      "data"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "properties": {
        +      "data": {
        +        "description": "Agent configuration payload",
        +        "properties": {
        +          "files": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Team files that should be available to the agent, each given as the relative file path returned in the `path` field of `GET /v2/teams/{teamId}/files` (for example `report.md` or `folder/doc.md`) — not the `id` field, which is a GCS object identifier."
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "items": {
        +                  "properties": {
        +                    "content": {
        +                      "anyOf": [
        +                        {
        +                          "type": "string"
        +                        },
        +                        {
        +                          "items": {
        +                            "anyOf": [
        +                              {
        +                                "properties": {
        +                                  "text": {
        +                                    "type": "string"
        +                                  },
        +                                  "type": {
        +                                    "const": "input_text",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "text"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              {
        +                                "properties": {
        +                                  "detail": {
        +                                    "anyOf": [
        +                                      {
        +                                        "enum": [
        +                                          "low",
        +                                          "high",
        +                                          "auto"
        +                                        ],
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  },
        +                                  "file_id": {
        +                                    "anyOf": [
        +                                      {
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  },
        +                                  "type": {
        +                                    "const": "input_image",
        +                                    "type": "string"
        +                                  },
        +                                  "url": {
        +                                    "anyOf": [
        +                                      {
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              {
        +                                "properties": {
        +                                  "file_id": {
        +                                    "type": "string"
        +                                  },
        +                                  "type": {
        +                                    "const": "input_file",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "file_id"
        +                                ],
        +                                "type": "object"
        +                              }
        +                            ]
        +                          },
        +                          "type": "array"
        +                        }
        +                      ]
        +                    },
        +                    "role": {
        +                      "enum": [
        +                        "system",
        +                        "user",
        +                        "assistant"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "type": {
        +                      "anyOf": [
        +                        {
        +                          "const": "message",
        +                          "type": "string"
        +                        },
        +                        {
        +                          "type": "null"
        +                        }
        +                      ]
        +                    }
        +                  },
        +                  "required": [
        +                    "role",
        +                    "content"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              }
        +            ],
        +            "description": "Initial agent instructions — either a single system prompt string or a list of structured messages"
        +          },
        +          "models": {
        +            "description": "Model configuration for each capability the agent uses",
        +            "properties": {
        +              "agent": {
        +                "description": "Primary agent model configuration",
        +                "properties": {
        +                  "model": {
        +                    "description": "Model identifier used for the primary agent loop (Claude, or an OSS model when the team's oss_models flag — or oss_models_public for the public subset — is enabled)",
        +                    "enum": [
        +                      "claude-haiku-4-5-20251001",
        +                      "claude-haiku-5-5",
        +                      "claude-haiku-5-5[1m]",
        +                      "claude-sonnet-5",
        +                      "claude-sonnet-5[1m]",
        +                      "claude-sonnet-5-5",
        +                      "claude-sonnet-5-5[1m]",
        +                      "claude-opus-5",
        +                      "claude-opus-5[1m]",
        +                      "claude-opus-5-5",
        +                      "claude-opus-5-5[1m]",
        +                      "kimi-k3",
        +                      "kimi-k3-duvo",
        +                      "glm-5.3-flash",
        +                      "deepseek-v4.1-flash",
        +                      "deepseek-v4.1-flash-1017",
        +                      "minimax-m3",
        +                      "d1-max",
        +                      "duvo-1-max",
        +                      "duvo-1-max-sonnet-1m",
        +                      "duvo-1-max-sonnet-4.5",
        +                      "duvo-1-max-sonnet-4.5-1m",
        +                      "duvo-1-max-opus",
        +                      "duvo-1-max-opus-4.5",
        +                      "gpt-4.1",
        +                      "gpt-4o",
        +                      "gpt-4o-mini",
        +                      "gpt-5",
        +                      "gpt-5.1",
        +                      "claude-sonnet-4-20250514",
        +                      "claude-sonnet-4-20250514[1m]",
        +                      "claude-sonnet-4-5-20250929",
        +                      "claude-sonnet-4-5-20250929[1m]",
        +                      "claude-sonnet-4-6",
        +                      "claude-sonnet-4-6[1m]",
        +                      "claude-opus-4-1-20250805",
        +                      "claude-opus-4-5-20251101",
        +                      "claude-opus-4-6",
        +                      "claude-opus-4-6[1m]",
        +                      "claude-opus-4-7",
        +                      "claude-opus-4-7[1m]",
        +                      "claude-opus-4-8",
        +                      "claude-opus-4-8[1m]",
        +                      "glm-5.2",
        +                      "qwen3.6-27b",
        +                      "qwen3.8-max",
        +                      "deepseek-v4-flash"
        +                    ],
        +                    "type": "string",
        +                    "x-extensible-enum": [
        +                      "claude-haiku-4-5-20251001",
        +                      "claude-haiku-5-5",
        +                      "claude-haiku-5-5[1m]",
        +                      "claude-sonnet-5",
        +                      "claude-sonnet-5[1m]",
        +                      "claude-sonnet-5-5",
        +                      "claude-sonnet-5-5[1m]",
        +                      "claude-opus-5",
        +                      "claude-opus-5[1m]",
        +                      "claude-opus-5-5",
        +                      "claude-opus-5-5[1m]",
        +                      "kimi-k3",
        +                      "kimi-k3-duvo",
        +                      "glm-5.3-flash",
        +                      "deepseek-v4.1-flash",
        +                      "deepseek-v4.1-flash-1017",
        +                      "minimax-m3",
        +                      "d1-max",
        +                      "duvo-1-max",
        +                      "duvo-1-max-sonnet-1m",
        +                      "duvo-1-max-sonnet-4.5",
        +                      "duvo-1-max-sonnet-4.5-1m",
        +                      "duvo-1-max-opus",
        +                      "duvo-1-max-opus-4.5",
        +                      "gpt-4.1",
        +                      "gpt-4o",
        +                      "gpt-4o-mini",
        +                      "gpt-5",
        +                      "gpt-5.1",
        +                      "claude-sonnet-4-20250514",
        +                      "claude-sonnet-4-20250514[1m]",
        +                      "claude-sonnet-4-5-20250929",
        +                      "claude-sonnet-4-5-20250929[1m]",
        +                      "claude-sonnet-4-6",
        +                      "claude-sonnet-4-6[1m]",
        +                      "claude-opus-4-1-20250805",
        +                      "claude-opus-4-5-20251101",
        +                      "claude-opus-4-6",
        +                      "claude-opus-4-6[1m]",
        +                      "claude-opus-4-7",
        +                      "claude-opus-4-7[1m]",
        +                      "claude-opus-4-8",
        +                      "claude-opus-4-8[1m]",
        +                      "glm-5.2",
        +                      "qwen3.6-27b",
        +                      "qwen3.8-max",
        +                      "deepseek-v4-flash"
        +                    ]
        +                  }
        +                },
        +                "required": [
        +                  "model"
        +                ],
        +                "type": "object"
        +              },
        +              "browsing": {
        +                "description": "Browsing/computer-use model configuration",
        +                "properties": {
        +                  "model": {
        +                    "description": "Model identifier for the browsing provider",
        +                    "enum": [
        +                      "gemini-2.5-pro",
        +                      "gemini-2.5-flash",
        +                      "gemini-3-pro-preview",
        +                      "claude-haiku-4-5",
        +                      "claude-sonnet-4-5",
        +                      "claude-opus-4-1"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "provider": {
        +                    "description": "Provider backing the browsing/computer-use model",
        +                    "enum": [
        +                      "google",
        +                      "anthropic"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "provider",
        +                  "model"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "agent",
        +              "browsing"
        +            ],
        +            "type": "object"
        +          },
        +          "options": {
        +            "additionalProperties": {},
        +            "description": "Optional runtime options controlling how the agent executes",
        +            "properties": {
        +              "benchmarkExpectedOutcomes": {
        +                "description": "Expected outcomes used when running benchmark scenarios",
        +                "items": {
        +                  "properties": {
        +                    "criteria": {
        +                      "description": "Pass/fail criteria used to evaluate the outcome",
        +                      "type": "string"
        +                    },
        +                    "description": {
        +                      "description": "Human-readable description of the expected outcome",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "description",
        +                    "criteria"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "browserProvider": {
        +                "description": "Browser infrastructure provider",
        +                "enum": [
        +                  "browserbase",
        +                  "browser-use"
        +                ],
        +                "type": "string"
        +              },
        +              "evaluationSchemaId": {
        +                "description": "ID of the evaluation schema to apply to runs of this agent",
        +                "type": "string"
        +              },
        +              "supervisedMode": {
        +                "description": "Run the agent under Duvo's permission classifier: every tool call is classified as allow/deny/ask, with 'ask' routed to human-in-the-loop approval. Mutually exclusive with browsing and computer-use connections.",
        +                "type": "boolean"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "plugins": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Plugins to load — either a built-in plugin name (e.g. \"code-review\") or a GitHub URL (e.g. \"https://github.com/owner/repo\")"
        +          },
        +          "skills": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "IDs of skills (team or system) that should be available to the agent"
        +          },
        +          "subAgents": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Retired — Sub-Assignments was removed. Accepted for backwards compatibility and ignored."
        +          }
        +        },
        +        "required": [
        +          "models",
        +          "input"
        +        ],
        +        "type": "object"
        +      },
        +      "version": {
        +        "const": "v2",
        +        "description": "Schema version discriminator — must be \"v2\" for the current schema",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "version",
        +      "data"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "data": {
        +        "description": "Code step configuration payload",
        +        "properties": {
        +          "files": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Team file paths this step can read at run time"
        +          },
        +          "handoverRequired": {
        +            "default": false,
        +            "description": "When the step declares handover options, whether a run that exits cleanly without requesting one fails. Ignored when the step declares no options.",
        +            "type": "boolean"
        +          },
        +          "language": {
        +            "description": "Language the step's program is written in",
        +            "enum": [
        +              "python"
        +            ],
        +            "type": "string"
        +          },
        +          "maxConcurrency": {
        +            "description": "Most runs of this step that may be in flight at once on one queue, on top of the queue's own concurrency. Absent means only the queue's limit applies. Every claim enforces it; only cases handed to the step (handover, postpone, reprocess) are also kept out of the queue's free slots while the step is full. Cases a trigger or a revision route sends straight to a capped step can still take queue slots and wait there, delaying other steps on the same queue.",
        +            "exclusiveMinimum": 0,
        +            "maximum": 1000,
        +            "type": "integer"
        +          },
        +          "source": {
        +            "description": "Where the step's program comes from",
        +            "oneOf": [
        +              {
        +                "properties": {
        +                  "code": {
        +                    "description": "Program held in the build config. Written to `main.py` and run with `python main.py`.",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "kind": {
        +                    "const": "inline",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "kind",
        +                  "code"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "properties": {
        +                  "bundle": {
        +                    "description": "The program's files, as a content-addressed manifest",
        +                    "properties": {
        +                      "bucket": {
        +                        "description": "GCS bucket the bundle's blobs are stored in",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "files": {
        +                        "description": "The program's files, one manifest entry each",
        +                        "items": {
        +                          "properties": {
        +                            "path": {
        +                              "description": "Path the file is materialised at, relative to the work dir",
        +                              "minLength": 1,
        +                              "type": "string"
        +                            },
        +                            "sha256": {
        +                              "description": "Digest of the file's bytes, and the key its blob is stored at",
        +                              "maxLength": 64,
        +                              "minLength": 64,
        +                              "pattern": "^[0-9a-f]{64}$",
        +                              "type": "string"
        +                            },
        +                            "sizeBytes": {
        +                              "description": "UTF-8 byte length of the file's contents",
        +                              "maximum": 131072,
        +                              "minimum": 0,
        +                              "type": "integer"
        +                            }
        +                          },
        +                          "required": [
        +                            "path",
        +                            "sha256",
        +                            "sizeBytes"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "maxItems": 200,
        +                        "type": "array"
        +                      }
        +                    },
        +                    "required": [
        +                      "bucket",
        +                      "files"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "kind": {
        +                    "const": "files",
        +                    "type": "string"
        +                  },
        +                  "startCommand": {
        +                    "description": "Command run from the root of the step's file system, e.g. \"python main.py\".",
        +                    "maxLength": 2000,
        +                    "minLength": 1,
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "kind",
        +                  "startCommand"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "timeoutMs": {
        +            "default": 600000,
        +            "description": "Wall-clock budget for one execution of the step",
        +            "exclusiveMinimum": 0,
        +            "maximum": 3600000,
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "language",
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "version": {
        +        "const": "v1",
        +        "description": "Schema version discriminator — must be \"v1\" for the current code-step schema",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "version",
        +      "data"
        +    ],
        +    "type": "object"
        +  }
        +]
    • RemoveddismissClarityCaptureSuggestion
    • ChangedproposeClarityLandscapeProcess1 field changed
      • changedInput schema / properties / materializationMode / description
        Previous value: -"Use \"proposal\" to record a process the organization plausibly needs, owned by `teamId` for review, WITHOUT creating a real process record. `teamId` is then required. Chat-scoped discovery agents may use proposal mode for their pinned team; direct human and API callers require Manager-or-above authority for that team. A proposal is idempotent: an equivalent live proposal under the same parent is returned untouched rather than duplicated. Defaults to \"auto\", which materializes a real process when `teamId` is set — except in a landscape-onboarding chat, which may only propose, and so defaults to \"proposal\"."New value: +"Use \"proposal\" to record a process the organization plausibly needs, owned by `teamId` for review, WITHOUT creating a real process record. `teamId` is then required. Chat-scoped callers may only propose for their pinned team; every caller needs Manager-or-above authority for that team. A proposal is idempotent: an equivalent live proposal under the same parent is returned untouched rather than duplicated. Defaults to \"auto\", which materializes a real process when `teamId` is set."
  7. 1 tool update
    • AddedsetUpModule
  8. 1 tool update
    • ChangedgenerateRevision2 fields changed
      • addedInput schema / properties / draft_file_id
        Added value: +{
        +  "description": "Temporary source file for this AOP draft. It is not kept on the Agent.",
        +  "format": "uuid",
        +  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +  "type": "string"
        +}
      • addedInput schema / properties / draft_file_ids
        Added value: +{
        +  "description": "Temporary source files for this AOP draft, in attachment order. They are not kept on the Agent.",
        +  "items": {
        +    "format": "uuid",
        +    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +    "type": "string"
        +  },
        +  "maxItems": 20,
        +  "type": "array"
        +}
  9. 2 tool updates
    • ChangedupdateClarityProcess1 field changed
      • addedInput schema / properties / mapLanguage
        Added value: +{
        +  "anyOf": [
        +    {
        +      "enum": [
        +        "cs",
        +        "de",
        +        "de-CH",
        +        "en",
        +        "en-GB",
        +        "es",
        +        "es-MX",
        +        "fr",
        +        "hu",
        +        "pl",
        +        "pt",
        +        "pt-BR",
        +        "sk",
        +        "sl",
        +        "th",
        +        "uk",
        +        "ar-EG",
        +        "ar-SA",
        +        "da-DK",
        +        "de-AT",
        +        "el-GR",
        +        "en-AU",
        +        "en-GB-scotland",
        +        "en-IE",
        +        "en-IN",
        +        "en-NG",
        +        "en-ZA",
        +        "es-AR",
        +        "fi-FI",
        +        "fr-BE",
        +        "fr-CA",
        +        "gsw-CH",
        +        "he-IL",
        +        "hi-IN",
        +        "hi-Latn-IN",
        +        "id-ID",
        +        "it-IT",
        +        "ja-JP",
        +        "ko-KR",
        +        "nb-NO",
        +        "nl-BE",
        +        "nl-NL",
        +        "ro-RO",
        +        "sv-SE",
        +        "tr-TR",
        +        "vi-VN",
        +        "yue-HK",
        +        "zh-Hans-CN",
        +        "zh-Hant-TW",
        +        "af-ZA",
        +        "ak-GH",
        +        "sq-AL",
        +        "am-ET",
        +        "hy-AM",
        +        "as-IN",
        +        "az-AZ",
        +        "eu-ES",
        +        "be-BY",
        +        "bn-BD",
        +        "bs-BA",
        +        "bg-BG",
        +        "my-MM",
        +        "ca-ES",
        +        "ceb-PH",
        +        "hr-HR",
        +        "et-EE",
        +        "fo-FO",
        +        "fil-PH",
        +        "gl-ES",
        +        "ka-GE",
        +        "gu-IN",
        +        "ha-NG",
        +        "is-IS",
        +        "ga-IE",
        +        "kn-IN",
        +        "kk-KZ",
        +        "km-KH",
        +        "rw-RW",
        +        "ku-TR",
        +        "ky-KG",
        +        "lo-LA",
        +        "lv-LV",
        +        "lt-LT",
        +        "mk-MK",
        +        "ms-MY",
        +        "ml-IN",
        +        "mt-MT",
        +        "mi-NZ",
        +        "mr-IN",
        +        "mn-MN",
        +        "ne-NP",
        +        "or-IN",
        +        "om-ET",
        +        "ps-AF",
        +        "fa-IR",
        +        "pa-IN",
        +        "qu-PE",
        +        "rm-CH",
        +        "ru-RU",
        +        "sr-RS",
        +        "sd-PK",
        +        "si-LK",
        +        "so-SO",
        +        "st-ZA",
        +        "sw-TZ",
        +        "tg-TJ",
        +        "ta-IN",
        +        "te-IN",
        +        "tn-ZA",
        +        "tk-TM",
        +        "ur-PK",
        +        "uz-UZ",
        +        "cy-GB",
        +        "fy-NL",
        +        "wo-SN",
        +        "yo-NG",
        +        "zu-ZA",
        +        "bn-IN",
        +        "ur-IN",
        +        "fr-CH",
        +        "it-CH",
        +        "de-BE",
        +        "sw-KE",
        +        "sw-UG",
        +        "ms-SG",
        +        "zh-Hans-SG",
        +        "ta-SG",
        +        "ta-LK",
        +        "yue-CN",
        +        "ar-IL",
        +        "ar-MA",
        +        "fr-MA",
        +        "sv-FI",
        +        "es-US",
        +        "ru-BY",
        +        "ru-KZ",
        +        "fa-AF",
        +        "ar-DZ",
        +        "fr-DZ",
        +        "ar-TN",
        +        "fr-TN",
        +        "ar-LY",
        +        "ar-SD",
        +        "ar-IQ",
        +        "ku-IQ",
        +        "ar-SY",
        +        "ar-JO",
        +        "ar-AE",
        +        "ar-QA",
        +        "ar-KW",
        +        "ar-OM",
        +        "ar-YE",
        +        "ar-LB",
        +        "fr-LB",
        +        "pt-AO",
        +        "pt-MZ",
        +        "es-CO",
        +        "es-PE",
        +        "es-CL",
        +        "es-VE",
        +        "es-EC",
        +        "es-BO",
        +        "qu-BO",
        +        "es-PY",
        +        "es-UY",
        +        "es-CU",
        +        "es-GT",
        +        "es-HN",
        +        "es-NI",
        +        "es-CR",
        +        "es-PA",
        +        "es-DO",
        +        "es-SV",
        +        "sr-ME",
        +        "fr-CD",
        +        "fr-CI",
        +        "fr-SN",
        +        "fr-ML",
        +        "fr-CM",
        +        "da-GL",
        +        "tn-BW",
        +        "af-NA",
        +        "el-CY",
        +        "tr-CY",
        +        "fr-LU",
        +        "de-LU",
        +        "en-CA",
        +        "en-NZ",
        +        "en-SG",
        +        "en-PH",
        +        "en-KE",
        +        "en-GH",
        +        "en-PK"
        +      ],
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "Language Duvo writes this process's map in, or null to use the team's map language"
        +}
    • ChangedupdateClarityTeamSettings1 field changed
      • addedInput schema / properties / mapLanguage
        Added value: +{
        +  "enum": [
        +    "cs",
        +    "de",
        +    "de-CH",
        +    "en",
        +    "en-GB",
        +    "es",
        +    "es-MX",
        +    "fr",
        +    "hu",
        +    "pl",
        +    "pt",
        +    "pt-BR",
        +    "sk",
        +    "sl",
        +    "th",
        +    "uk",
        +    "ar-EG",
        +    "ar-SA",
        +    "da-DK",
        +    "de-AT",
        +    "el-GR",
        +    "en-AU",
        +    "en-GB-scotland",
        +    "en-IE",
        +    "en-IN",
        +    "en-NG",
        +    "en-ZA",
        +    "es-AR",
        +    "fi-FI",
        +    "fr-BE",
        +    "fr-CA",
        +    "gsw-CH",
        +    "he-IL",
        +    "hi-IN",
        +    "hi-Latn-IN",
        +    "id-ID",
        +    "it-IT",
        +    "ja-JP",
        +    "ko-KR",
        +    "nb-NO",
        +    "nl-BE",
        +    "nl-NL",
        +    "ro-RO",
        +    "sv-SE",
        +    "tr-TR",
        +    "vi-VN",
        +    "yue-HK",
        +    "zh-Hans-CN",
        +    "zh-Hant-TW",
        +    "af-ZA",
        +    "ak-GH",
        +    "sq-AL",
        +    "am-ET",
        +    "hy-AM",
        +    "as-IN",
        +    "az-AZ",
        +    "eu-ES",
        +    "be-BY",
        +    "bn-BD",
        +    "bs-BA",
        +    "bg-BG",
        +    "my-MM",
        +    "ca-ES",
        +    "ceb-PH",
        +    "hr-HR",
        +    "et-EE",
        +    "fo-FO",
        +    "fil-PH",
        +    "gl-ES",
        +    "ka-GE",
        +    "gu-IN",
        +    "ha-NG",
        +    "is-IS",
        +    "ga-IE",
        +    "kn-IN",
        +    "kk-KZ",
        +    "km-KH",
        +    "rw-RW",
        +    "ku-TR",
        +    "ky-KG",
        +    "lo-LA",
        +    "lv-LV",
        +    "lt-LT",
        +    "mk-MK",
        +    "ms-MY",
        +    "ml-IN",
        +    "mt-MT",
        +    "mi-NZ",
        +    "mr-IN",
        +    "mn-MN",
        +    "ne-NP",
        +    "or-IN",
        +    "om-ET",
        +    "ps-AF",
        +    "fa-IR",
        +    "pa-IN",
        +    "qu-PE",
        +    "rm-CH",
        +    "ru-RU",
        +    "sr-RS",
        +    "sd-PK",
        +    "si-LK",
        +    "so-SO",
        +    "st-ZA",
        +    "sw-TZ",
        +    "tg-TJ",
        +    "ta-IN",
        +    "te-IN",
        +    "tn-ZA",
        +    "tk-TM",
        +    "ur-PK",
        +    "uz-UZ",
        +    "cy-GB",
        +    "fy-NL",
        +    "wo-SN",
        +    "yo-NG",
        +    "zu-ZA",
        +    "bn-IN",
        +    "ur-IN",
        +    "fr-CH",
        +    "it-CH",
        +    "de-BE",
        +    "sw-KE",
        +    "sw-UG",
        +    "ms-SG",
        +    "zh-Hans-SG",
        +    "ta-SG",
        +    "ta-LK",
        +    "yue-CN",
        +    "ar-IL",
        +    "ar-MA",
        +    "fr-MA",
        +    "sv-FI",
        +    "es-US",
        +    "ru-BY",
        +    "ru-KZ",
        +    "fa-AF",
        +    "ar-DZ",
        +    "fr-DZ",
        +    "ar-TN",
        +    "fr-TN",
        +    "ar-LY",
        +    "ar-SD",
        +    "ar-IQ",
        +    "ku-IQ",
        +    "ar-SY",
        +    "ar-JO",
        +    "ar-AE",
        +    "ar-QA",
        +    "ar-KW",
        +    "ar-OM",
        +    "ar-YE",
        +    "ar-LB",
        +    "fr-LB",
        +    "pt-AO",
        +    "pt-MZ",
        +    "es-CO",
        +    "es-PE",
        +    "es-CL",
        +    "es-VE",
        +    "es-EC",
        +    "es-BO",
        +    "qu-BO",
        +    "es-PY",
        +    "es-UY",
        +    "es-CU",
        +    "es-GT",
        +    "es-HN",
        +    "es-NI",
        +    "es-CR",
        +    "es-PA",
        +    "es-DO",
        +    "es-SV",
        +    "sr-ME",
        +    "fr-CD",
        +    "fr-CI",
        +    "fr-SN",
        +    "fr-ML",
        +    "fr-CM",
        +    "da-GL",
        +    "tn-BW",
        +    "af-NA",
        +    "el-CY",
        +    "tr-CY",
        +    "fr-LU",
        +    "de-LU",
        +    "en-CA",
        +    "en-NZ",
        +    "en-SG",
        +    "en-PH",
        +    "en-KE",
        +    "en-GH",
        +    "en-PK"
        +  ],
        +  "type": "string"
        +}
  10. 4 tool updates
    • AddedbulkGenerateClarityProcessSnapshots
    • ChangedinviteClarityMeetingNotetaker1 field changed
      • addedInput schema / properties / joinAt
        Added value: +{
        +  "format": "date-time",
        +  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
        +  "type": "string"
        +}
    • ChangedinviteClarityOrganizationNotetaker1 field changed
      • addedInput schema / properties / joinAt
        Added value: +{
        +  "format": "date-time",
        +  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
        +  "type": "string"
        +}
    • ChangedsaveClarityProcessSnapshot1 field changed
      • changedInput schema / properties / steps / items / anyOf
        Previous value: -[
        -  {
        -    "oneOf": [
        -      {
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Always null on events; included for shape compatibility across variants."
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "conflicts": {
        -            "items": {
        -              "properties": {
        -                "id": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "mappedVersionIndex": {
        -                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        -                  "maximum": 9007199254740991,
        -                  "minimum": 0,
        -                  "type": "integer"
        -                },
        -                "question": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "versions": {
        -                  "items": {
        -                    "properties": {
        -                      "attribution": {
        -                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "captureId": {
        -                        "format": "uuid",
        -                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                        "type": "string"
        -                      },
        -                      "evidenceId": {
        -                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "excerpt": {
        -                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "locator": {
        -                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                        "oneOf": [
        -                          {
        -                            "properties": {
        -                              "messageIndex": {
        -                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "timestampMs": {
        -                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "transcript_message",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "messageIndex"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "endLine": {
        -                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "endOffset": {
        -                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "pageNumber": {
        -                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startLine": {
        -                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startOffset": {
        -                                "description": "Zero-based character offset into the stored capture text.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "document_text_range",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "startOffset",
        -                              "endOffset"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "elementId": {
        -                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "elementType": {
        -                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "name": {
        -                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "bpmn_element",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "elementId"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "timestampMs": {
        -                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "screenshare_frame",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "timestampMs"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "type": {
        -                                "const": "manual",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "reason": {
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "unresolved",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          }
        -                        ]
        -                      },
        -                      "resolutionStatus": {
        -                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                        "enum": [
        -                          "resolved",
        -                          "unresolved",
        -                          "legacy",
        -                          "manual"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "sourceConfidence": {
        -                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                        "enum": [
        -                          "low",
        -                          "medium",
        -                          "high"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "title": {
        -                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "attribution",
        -                      "excerpt",
        -                      "captureId"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "minItems": 2,
        -                  "type": "array"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "question",
        -                "versions"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional prose describing what happens at this event. May be null for structural markers."
        -          },
        -          "effort": {
        -            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        -            "items": {
        -              "properties": {
        -                "basis": {
        -                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        -                  "enum": [
        -                    "stated",
        -                    "estimated",
        -                    "unknown"
        -                  ],
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "count": {
        -                          "description": "How many times the work happens per period. Example: 40",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the count covers. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "count",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How often the work happens for this person. Null unless they gave a count."
        -                },
        -                "person": {
        -                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "timeSpent": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "hours": {
        -                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the hours cover. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "hours",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        -                }
        -              },
        -              "required": [
        -                "person",
        -                "timeSpent",
        -                "frequency",
        -                "basis",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "exceptions": {
        -            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        -            "items": {
        -              "properties": {
        -                "exception": {
        -                  "description": "A distinct failure mode that can happen at this step.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "enum": [
        -                        "rare",
        -                        "occasional",
        -                        "frequent"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        -                },
        -                "handling": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How the team responds to this exception. Null when the response was not documented."
        -                },
        -                "id": {
        -                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "exception",
        -                "handling",
        -                "frequency"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "extraCaptureNeeds": {
        -            "items": {
        -              "properties": {
        -                "gap": {
        -                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "id": {
        -                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                  "type": "string"
        -                },
        -                "proposal": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "gap"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN event subtype. \"start\" (entry trigger), \"end\" (terminal state), \"timer\" (time-based wait; title it with the duration, deadline, or cadence the captures give, e.g. \"Supplier reply: 2-3 days\"), \"message\" (external communication), \"escalation\" (route to higher authority).",
        -            "enum": [
        -              "start",
        -              "end",
        -              "timer",
        -              "message",
        -              "escalation"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "event",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional reason for the event's existence. May be null for structural markers."
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exceptions",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      },
        -      {
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional precondition that gates this task. Null when the task is unconditional. Example: \"Only when invoice total exceeds $10,000\""
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "conflicts": {
        -            "items": {
        -              "properties": {
        -                "id": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "mappedVersionIndex": {
        -                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        -                  "maximum": 9007199254740991,
        -                  "minimum": 0,
        -                  "type": "integer"
        -                },
        -                "question": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "versions": {
        -                  "items": {
        -                    "properties": {
        -                      "attribution": {
        -                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "captureId": {
        -                        "format": "uuid",
        -                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                        "type": "string"
        -                      },
        -                      "evidenceId": {
        -                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "excerpt": {
        -                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "locator": {
        -                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                        "oneOf": [
        -                          {
        -                            "properties": {
        -                              "messageIndex": {
        -                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "timestampMs": {
        -                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "transcript_message",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "messageIndex"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "endLine": {
        -                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "endOffset": {
        -                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "pageNumber": {
        -                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startLine": {
        -                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startOffset": {
        -                                "description": "Zero-based character offset into the stored capture text.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "document_text_range",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "startOffset",
        -                              "endOffset"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "elementId": {
        -                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "elementType": {
        -                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "name": {
        -                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "bpmn_element",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "elementId"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "timestampMs": {
        -                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "screenshare_frame",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "timestampMs"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "type": {
        -                                "const": "manual",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "reason": {
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "unresolved",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          }
        -                        ]
        -                      },
        -                      "resolutionStatus": {
        -                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                        "enum": [
        -                          "resolved",
        -                          "unresolved",
        -                          "legacy",
        -                          "manual"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "sourceConfidence": {
        -                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                        "enum": [
        -                          "low",
        -                          "medium",
        -                          "high"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "title": {
        -                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "attribution",
        -                      "excerpt",
        -                      "captureId"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "minItems": 2,
        -                  "type": "array"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "question",
        -                "versions"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "description": "Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: \"Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval.\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "effort": {
        -            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        -            "items": {
        -              "properties": {
        -                "basis": {
        -                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        -                  "enum": [
        -                    "stated",
        -                    "estimated",
        -                    "unknown"
        -                  ],
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "count": {
        -                          "description": "How many times the work happens per period. Example: 40",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the count covers. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "count",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How often the work happens for this person. Null unless they gave a count."
        -                },
        -                "person": {
        -                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "timeSpent": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "hours": {
        -                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the hours cover. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "hours",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        -                }
        -              },
        -              "required": [
        -                "person",
        -                "timeSpent",
        -                "frequency",
        -                "basis",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "exceptions": {
        -            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        -            "items": {
        -              "properties": {
        -                "exception": {
        -                  "description": "A distinct failure mode that can happen at this step.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "enum": [
        -                        "rare",
        -                        "occasional",
        -                        "frequent"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        -                },
        -                "handling": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How the team responds to this exception. Null when the response was not documented."
        -                },
        -                "id": {
        -                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "exception",
        -                "handling",
        -                "frequency"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "extraCaptureNeeds": {
        -            "items": {
        -              "properties": {
        -                "gap": {
        -                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "id": {
        -                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                  "type": "string"
        -                },
        -                "proposal": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "gap"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN task subtype. \"user\" (human work), \"service\" (automated/API call), \"send\"/\"receive\" (messaging), \"manual\" (offline physical work), \"businessRule\" (rule engine), \"script\" (code execution).",
        -            "enum": [
        -              "user",
        -              "service",
        -              "send",
        -              "receive",
        -              "manual",
        -              "businessRule",
        -              "script"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "task",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "description": "Why this step exists in the process — its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: \"Catches mispriced line items before they reach the customer and prevents downstream credit notes.\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting this step's existence and details. At least one source is required — every step must trace back to something in the captures.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exceptions",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      },
        -      {
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "description": "Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as \"unknown\" via a read-side preprocess; producers should write a real condition string going forward.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "conflicts": {
        -            "items": {
        -              "properties": {
        -                "id": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "mappedVersionIndex": {
        -                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        -                  "maximum": 9007199254740991,
        -                  "minimum": 0,
        -                  "type": "integer"
        -                },
        -                "question": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "versions": {
        -                  "items": {
        -                    "properties": {
        -                      "attribution": {
        -                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "captureId": {
        -                        "format": "uuid",
        -                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                        "type": "string"
        -                      },
        -                      "evidenceId": {
        -                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "excerpt": {
        -                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "locator": {
        -                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                        "oneOf": [
        -                          {
        -                            "properties": {
        -                              "messageIndex": {
        -                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "timestampMs": {
        -                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "transcript_message",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "messageIndex"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "endLine": {
        -                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "endOffset": {
        -                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "pageNumber": {
        -                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startLine": {
        -                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startOffset": {
        -                                "description": "Zero-based character offset into the stored capture text.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "document_text_range",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "startOffset",
        -                              "endOffset"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "elementId": {
        -                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "elementType": {
        -                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "name": {
        -                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "bpmn_element",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "elementId"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "timestampMs": {
        -                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "screenshare_frame",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "timestampMs"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "type": {
        -                                "const": "manual",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "reason": {
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "unresolved",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          }
        -                        ]
        -                      },
        -                      "resolutionStatus": {
        -                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                        "enum": [
        -                          "resolved",
        -                          "unresolved",
        -                          "legacy",
        -                          "manual"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "sourceConfidence": {
        -                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                        "enum": [
        -                          "low",
        -                          "medium",
        -                          "high"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "title": {
        -                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "attribution",
        -                      "excerpt",
        -                      "captureId"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "minItems": 2,
        -                  "type": "array"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "question",
        -                "versions"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "description": "Full prose describing the decision logic at this gateway.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "effort": {
        -            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        -            "items": {
        -              "properties": {
        -                "basis": {
        -                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        -                  "enum": [
        -                    "stated",
        -                    "estimated",
        -                    "unknown"
        -                  ],
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "count": {
        -                          "description": "How many times the work happens per period. Example: 40",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the count covers. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "count",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How often the work happens for this person. Null unless they gave a count."
        -                },
        -                "person": {
        -                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "timeSpent": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "hours": {
        -                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the hours cover. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "hours",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        -                }
        -              },
        -              "required": [
        -                "person",
        -                "timeSpent",
        -                "frequency",
        -                "basis",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "exceptions": {
        -            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        -            "items": {
        -              "properties": {
        -                "exception": {
        -                  "description": "A distinct failure mode that can happen at this step.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "enum": [
        -                        "rare",
        -                        "occasional",
        -                        "frequent"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        -                },
        -                "handling": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How the team responds to this exception. Null when the response was not documented."
        -                },
        -                "id": {
        -                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "exception",
        -                "handling",
        -                "frequency"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "extraCaptureNeeds": {
        -            "items": {
        -              "properties": {
        -                "gap": {
        -                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "id": {
        -                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                  "type": "string"
        -                },
        -                "proposal": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "gap"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN gateway subtype. \"exclusive\" (XOR — exactly one branch taken), \"parallel\" (AND — all branches taken), \"inclusive\" (OR — one or more branches taken).",
        -            "enum": [
        -              "exclusive",
        -              "parallel",
        -              "inclusive"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "gateway",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "description": "Why this branching decision exists in the process.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting the decision criteria.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exceptions",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      }
        -    ]
        -  },
        -  {
        -    "oneOf": [
        -      {
        -        "additionalProperties": false,
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Always null on events; included for shape compatibility across variants."
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "conflicts": {
        -            "items": {
        -              "properties": {
        -                "id": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "mappedVersionIndex": {
        -                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        -                  "maximum": 9007199254740991,
        -                  "minimum": 0,
        -                  "type": "integer"
        -                },
        -                "question": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "versions": {
        -                  "items": {
        -                    "properties": {
        -                      "attribution": {
        -                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "captureId": {
        -                        "format": "uuid",
        -                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                        "type": "string"
        -                      },
        -                      "evidenceId": {
        -                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "excerpt": {
        -                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "locator": {
        -                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                        "oneOf": [
        -                          {
        -                            "properties": {
        -                              "messageIndex": {
        -                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "timestampMs": {
        -                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "transcript_message",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "messageIndex"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "endLine": {
        -                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "endOffset": {
        -                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "pageNumber": {
        -                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startLine": {
        -                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startOffset": {
        -                                "description": "Zero-based character offset into the stored capture text.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "document_text_range",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "startOffset",
        -                              "endOffset"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "elementId": {
        -                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "elementType": {
        -                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "name": {
        -                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "bpmn_element",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "elementId"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "timestampMs": {
        -                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "screenshare_frame",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "timestampMs"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "type": {
        -                                "const": "manual",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "reason": {
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "unresolved",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          }
        -                        ]
        -                      },
        -                      "resolutionStatus": {
        -                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                        "enum": [
        -                          "resolved",
        -                          "unresolved",
        -                          "legacy",
        -                          "manual"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "sourceConfidence": {
        -                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                        "enum": [
        -                          "low",
        -                          "medium",
        -                          "high"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "title": {
        -                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "attribution",
        -                      "excerpt",
        -                      "captureId"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "minItems": 2,
        -                  "type": "array"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "question",
        -                "versions"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional prose describing what happens at this event. May be null for structural markers."
        -          },
        -          "effort": {
        -            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        -            "items": {
        -              "properties": {
        -                "basis": {
        -                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        -                  "enum": [
        -                    "stated",
        -                    "estimated",
        -                    "unknown"
        -                  ],
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "count": {
        -                          "description": "How many times the work happens per period. Example: 40",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the count covers. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "count",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How often the work happens for this person. Null unless they gave a count."
        -                },
        -                "person": {
        -                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "timeSpent": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "hours": {
        -                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the hours cover. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "hours",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        -                }
        -              },
        -              "required": [
        -                "person",
        -                "timeSpent",
        -                "frequency",
        -                "basis",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "exception": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "extraCaptureNeeds": {
        -            "items": {
        -              "properties": {
        -                "gap": {
        -                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "id": {
        -                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                  "type": "string"
        -                },
        -                "proposal": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "gap"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "handling": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN event subtype. \"start\" (entry trigger), \"end\" (terminal state), \"timer\" (time-based wait; title it with the duration, deadline, or cadence the captures give, e.g. \"Supplier reply: 2-3 days\"), \"message\" (external communication), \"escalation\" (route to higher authority).",
        -            "enum": [
        -              "start",
        -              "end",
        -              "timer",
        -              "message",
        -              "escalation"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "event",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional reason for the event's existence. May be null for structural markers."
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exception",
        -          "handling",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      },
        -      {
        -        "additionalProperties": false,
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional precondition that gates this task. Null when the task is unconditional. Example: \"Only when invoice total exceeds $10,000\""
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "conflicts": {
        -            "items": {
        -              "properties": {
        -                "id": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "mappedVersionIndex": {
        -                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        -                  "maximum": 9007199254740991,
        -                  "minimum": 0,
        -                  "type": "integer"
        -                },
        -                "question": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "versions": {
        -                  "items": {
        -                    "properties": {
        -                      "attribution": {
        -                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "captureId": {
        -                        "format": "uuid",
        -                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                        "type": "string"
        -                      },
        -                      "evidenceId": {
        -                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "excerpt": {
        -                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "locator": {
        -                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                        "oneOf": [
        -                          {
        -                            "properties": {
        -                              "messageIndex": {
        -                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "timestampMs": {
        -                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "transcript_message",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "messageIndex"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "endLine": {
        -                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "endOffset": {
        -                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "pageNumber": {
        -                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startLine": {
        -                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startOffset": {
        -                                "description": "Zero-based character offset into the stored capture text.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "document_text_range",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "startOffset",
        -                              "endOffset"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "elementId": {
        -                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "elementType": {
        -                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "name": {
        -                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "bpmn_element",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "elementId"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "timestampMs": {
        -                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "screenshare_frame",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "timestampMs"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "type": {
        -                                "const": "manual",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "reason": {
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "unresolved",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          }
        -                        ]
        -                      },
        -                      "resolutionStatus": {
        -                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                        "enum": [
        -                          "resolved",
        -                          "unresolved",
        -                          "legacy",
        -                          "manual"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "sourceConfidence": {
        -                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                        "enum": [
        -                          "low",
        -                          "medium",
        -                          "high"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "title": {
        -                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "attribution",
        -                      "excerpt",
        -                      "captureId"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "minItems": 2,
        -                  "type": "array"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "question",
        -                "versions"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "description": "Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: \"Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval.\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "effort": {
        -            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        -            "items": {
        -              "properties": {
        -                "basis": {
        -                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        -                  "enum": [
        -                    "stated",
        -                    "estimated",
        -                    "unknown"
        -                  ],
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "count": {
        -                          "description": "How many times the work happens per period. Example: 40",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the count covers. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "count",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How often the work happens for this person. Null unless they gave a count."
        -                },
        -                "person": {
        -                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "timeSpent": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "hours": {
        -                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the hours cover. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "hours",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        -                }
        -              },
        -              "required": [
        -                "person",
        -                "timeSpent",
        -                "frequency",
        -                "basis",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "exception": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "extraCaptureNeeds": {
        -            "items": {
        -              "properties": {
        -                "gap": {
        -                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "id": {
        -                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                  "type": "string"
        -                },
        -                "proposal": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "gap"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "handling": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN task subtype. \"user\" (human work), \"service\" (automated/API call), \"send\"/\"receive\" (messaging), \"manual\" (offline physical work), \"businessRule\" (rule engine), \"script\" (code execution).",
        -            "enum": [
        -              "user",
        -              "service",
        -              "send",
        -              "receive",
        -              "manual",
        -              "businessRule",
        -              "script"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "task",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "description": "Why this step exists in the process — its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: \"Catches mispriced line items before they reach the customer and prevents downstream credit notes.\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting this step's existence and details. At least one source is required — every step must trace back to something in the captures.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exception",
        -          "handling",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      },
        -      {
        -        "additionalProperties": false,
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "description": "Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as \"unknown\" via a read-side preprocess; producers should write a real condition string going forward.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "conflicts": {
        -            "items": {
        -              "properties": {
        -                "id": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "mappedVersionIndex": {
        -                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        -                  "maximum": 9007199254740991,
        -                  "minimum": 0,
        -                  "type": "integer"
        -                },
        -                "question": {
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "versions": {
        -                  "items": {
        -                    "properties": {
        -                      "attribution": {
        -                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "captureId": {
        -                        "format": "uuid",
        -                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                        "type": "string"
        -                      },
        -                      "evidenceId": {
        -                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "excerpt": {
        -                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "locator": {
        -                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                        "oneOf": [
        -                          {
        -                            "properties": {
        -                              "messageIndex": {
        -                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "timestampMs": {
        -                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "transcript_message",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "messageIndex"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "endLine": {
        -                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "endOffset": {
        -                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "pageNumber": {
        -                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startLine": {
        -                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                                "exclusiveMinimum": 0,
        -                                "maximum": 9007199254740991,
        -                                "type": "integer"
        -                              },
        -                              "startOffset": {
        -                                "description": "Zero-based character offset into the stored capture text.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "document_text_range",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "startOffset",
        -                              "endOffset"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "elementId": {
        -                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "elementType": {
        -                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "name": {
        -                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "bpmn_element",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "elementId"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "timestampMs": {
        -                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                                "maximum": 9007199254740991,
        -                                "minimum": 0,
        -                                "type": "integer"
        -                              },
        -                              "type": {
        -                                "const": "screenshare_frame",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type",
        -                              "timestampMs"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "type": {
        -                                "const": "manual",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          },
        -                          {
        -                            "properties": {
        -                              "reason": {
        -                                "minLength": 1,
        -                                "type": "string"
        -                              },
        -                              "type": {
        -                                "const": "unresolved",
        -                                "type": "string"
        -                              }
        -                            },
        -                            "required": [
        -                              "type"
        -                            ],
        -                            "type": "object"
        -                          }
        -                        ]
        -                      },
        -                      "resolutionStatus": {
        -                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                        "enum": [
        -                          "resolved",
        -                          "unresolved",
        -                          "legacy",
        -                          "manual"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "sourceConfidence": {
        -                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                        "enum": [
        -                          "low",
        -                          "medium",
        -                          "high"
        -                        ],
        -                        "type": "string"
        -                      },
        -                      "title": {
        -                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      }
        -                    },
        -                    "required": [
        -                      "attribution",
        -                      "excerpt",
        -                      "captureId"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "minItems": 2,
        -                  "type": "array"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "question",
        -                "versions"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "description": "Full prose describing the decision logic at this gateway.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "effort": {
        -            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        -            "items": {
        -              "properties": {
        -                "basis": {
        -                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        -                  "enum": [
        -                    "stated",
        -                    "estimated",
        -                    "unknown"
        -                  ],
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "count": {
        -                          "description": "How many times the work happens per period. Example: 40",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the count covers. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "count",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How often the work happens for this person. Null unless they gave a count."
        -                },
        -                "person": {
        -                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "timeSpent": {
        -                  "anyOf": [
        -                    {
        -                      "properties": {
        -                        "hours": {
        -                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        -                          "exclusiveMinimum": 0,
        -                          "type": "number"
        -                        },
        -                        "period": {
        -                          "description": "Period the hours cover. Example: \"day\"",
        -                          "enum": [
        -                            "day",
        -                            "week",
        -                            "month"
        -                          ],
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "hours",
        -                        "period"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        -                }
        -              },
        -              "required": [
        -                "person",
        -                "timeSpent",
        -                "frequency",
        -                "basis",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "exception": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "extraCaptureNeeds": {
        -            "items": {
        -              "properties": {
        -                "gap": {
        -                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "id": {
        -                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                  "type": "string"
        -                },
        -                "proposal": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "gap"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "handling": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN gateway subtype. \"exclusive\" (XOR — exactly one branch taken), \"parallel\" (AND — all branches taken), \"inclusive\" (OR — one or more branches taken).",
        -            "enum": [
        -              "exclusive",
        -              "parallel",
        -              "inclusive"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "gateway",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "description": "Why this branching decision exists in the process.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting the decision criteria.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exception",
        -          "handling",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      }
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "oneOf": [
        +      {
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Always null on events; included for shape compatibility across variants."
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional prose describing what happens at this event. May be null for structural markers."
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exceptions": {
        +            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        +            "items": {
        +              "properties": {
        +                "exception": {
        +                  "description": "A distinct failure mode that can happen at this step.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "enum": [
        +                        "rare",
        +                        "occasional",
        +                        "frequent"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        +                },
        +                "handling": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How the team responds to this exception. Null when the response was not documented."
        +                },
        +                "id": {
        +                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "exception",
        +                "handling",
        +                "frequency"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN event subtype. \"start\" (entry trigger), \"end\" (terminal state), \"timer\" (time-based wait; title it with the duration, deadline, or cadence the captures give, e.g. \"Supplier reply: 2-3 days\"), \"message\" (external communication), \"escalation\" (route to higher authority).",
        +            "enum": [
        +              "start",
        +              "end",
        +              "timer",
        +              "message",
        +              "escalation"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "event",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional reason for the event's existence. May be null for structural markers."
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exceptions",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional precondition that gates this task. Null when the task is unconditional. Example: \"Only when invoice total exceeds $10,000\""
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: \"Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval.\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exceptions": {
        +            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        +            "items": {
        +              "properties": {
        +                "exception": {
        +                  "description": "A distinct failure mode that can happen at this step.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "enum": [
        +                        "rare",
        +                        "occasional",
        +                        "frequent"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        +                },
        +                "handling": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How the team responds to this exception. Null when the response was not documented."
        +                },
        +                "id": {
        +                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "exception",
        +                "handling",
        +                "frequency"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN task subtype. \"user\" (human work), \"service\" (automated/API call), \"send\"/\"receive\" (messaging), \"manual\" (offline physical work), \"businessRule\" (rule engine), \"script\" (code execution).",
        +            "enum": [
        +              "user",
        +              "service",
        +              "send",
        +              "receive",
        +              "manual",
        +              "businessRule",
        +              "script"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "task",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "description": "Why this step exists in the process — its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: \"Catches mispriced line items before they reach the customer and prevents downstream credit notes.\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting this step's existence and details. At least one source is required — every step must trace back to something in the captures.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exceptions",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "description": "Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as \"unknown\" via a read-side preprocess; producers should write a real condition string going forward.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose describing the decision logic at this gateway.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exceptions": {
        +            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        +            "items": {
        +              "properties": {
        +                "exception": {
        +                  "description": "A distinct failure mode that can happen at this step.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "enum": [
        +                        "rare",
        +                        "occasional",
        +                        "frequent"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        +                },
        +                "handling": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How the team responds to this exception. Null when the response was not documented."
        +                },
        +                "id": {
        +                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "exception",
        +                "handling",
        +                "frequency"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN gateway subtype. \"exclusive\" (XOR — exactly one branch taken), \"parallel\" (AND — all branches taken), \"inclusive\" (OR — one or more branches taken).",
        +            "enum": [
        +              "exclusive",
        +              "parallel",
        +              "inclusive"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "gateway",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "description": "Why this branching decision exists in the process.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting the decision criteria.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exceptions",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      }
        +    ]
        +  },
        +  {
        +    "oneOf": [
        +      {
        +        "additionalProperties": false,
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Always null on events; included for shape compatibility across variants."
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional prose describing what happens at this event. May be null for structural markers."
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exception": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "handling": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN event subtype. \"start\" (entry trigger), \"end\" (terminal state), \"timer\" (time-based wait; title it with the duration, deadline, or cadence the captures give, e.g. \"Supplier reply: 2-3 days\"), \"message\" (external communication), \"escalation\" (route to higher authority).",
        +            "enum": [
        +              "start",
        +              "end",
        +              "timer",
        +              "message",
        +              "escalation"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "event",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional reason for the event's existence. May be null for structural markers."
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exception",
        +          "handling",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional precondition that gates this task. Null when the task is unconditional. Example: \"Only when invoice total exceeds $10,000\""
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: \"Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval.\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exception": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "handling": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN task subtype. \"user\" (human work), \"service\" (automated/API call), \"send\"/\"receive\" (messaging), \"manual\" (offline physical work), \"businessRule\" (rule engine), \"script\" (code execution).",
        +            "enum": [
        +              "user",
        +              "service",
        +              "send",
        +              "receive",
        +              "manual",
        +              "businessRule",
        +              "script"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "task",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "description": "Why this step exists in the process — its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: \"Catches mispriced line items before they reach the customer and prevents downstream credit notes.\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting this step's existence and details. At least one source is required — every step must trace back to something in the captures.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exception",
        +          "handling",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "description": "Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as \"unknown\" via a read-side preprocess; producers should write a real condition string going forward.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose describing the decision logic at this gateway.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exception": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "handling": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN gateway subtype. \"exclusive\" (XOR — exactly one branch taken), \"parallel\" (AND — all branches taken), \"inclusive\" (OR — one or more branches taken).",
        +            "enum": [
        +              "exclusive",
        +              "parallel",
        +              "inclusive"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "gateway",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "description": "Why this branching decision exists in the process.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting the decision criteria.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exception",
        +          "handling",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      }
        +    ]
        +  }
        +]
  11. 3 tool updates
    • AddedgetRevisionBody
    • ChangedlistAgentRevisions1 field changed
      • addedInput schema / properties / config
        Added value: +{
        +  "description": "`full` (default) embeds each revision's config. `light` sets `config` to null and reports its sizes, hash and models in `config_summary`; read the AOP or program text with getRevisionBody. Use `light` unless you need the instructions themselves: a page of revisions can run to millions of characters.",
        +  "enum": [
        +    "light",
        +    "full"
        +  ],
        +  "type": "string"
        +}
    • ChangedlistAgents1 field changed
      • addedInput schema / properties / config
        Added value: +{
        +  "description": "`full` (default) embeds each agent's live revision config in `latest_build.config`. `light` sets that to null and reports its sizes, hash and models in `latest_build_config_summary`; read the AOP or program text with getRevisionBody. Use `light` unless you need the instructions themselves: a full page can run to hundreds of thousands of characters.",
        +  "enum": [
        +    "light",
        +    "full"
        +  ],
        +  "type": "string"
        +}
  12. 1 tool update
    • ChangedupdateClarityProcess2 fields changed
      • changedInput schema / properties / status / description
        Previous value: -"Mark a review-stage process complete"New value: +"Mark a review-stage process complete, or reopen a completed process for review"
      • changedInput schema / properties / status / enum
        Previous value: -[
        -  "complete"
        -]New value: +[
        +  "complete",
        +  "review"
        +]
  13. 9 tool updates
    • AddedassignPolicyInterview
    • AddedassignProcessMember
    • AddedgetAutomationReadiness
    • AddedlistProcessRoles
    • AddedreadAutomationDashboardData
    • AddedreadAutomationPolicy
    • ChangedsaveClarityProcessSnapshot1 field changed
      • changedInput schema / properties / steps / items / anyOf
        Previous value: -[
        -  {
        -    "oneOf": [
        -      {
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Always null on events; included for shape compatibility across variants."
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional prose describing what happens at this event. May be null for structural markers."
        -          },
        -          "exceptions": {
        -            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        -            "items": {
        -              "properties": {
        -                "exception": {
        -                  "description": "A distinct failure mode that can happen at this step.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "enum": [
        -                        "rare",
        -                        "occasional",
        -                        "frequent"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        -                },
        -                "handling": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How the team responds to this exception. Null when the response was not documented."
        -                },
        -                "id": {
        -                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "exception",
        -                "handling",
        -                "frequency"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN event subtype. \"start\" (entry trigger), \"end\" (terminal state), \"timer\" (time-based wait; title it with the duration, deadline, or cadence the captures give, e.g. \"Supplier reply: 2-3 days\"), \"message\" (external communication), \"escalation\" (route to higher authority).",
        -            "enum": [
        -              "start",
        -              "end",
        -              "timer",
        -              "message",
        -              "escalation"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "event",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional reason for the event's existence. May be null for structural markers."
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exceptions",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      },
        -      {
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional precondition that gates this task. Null when the task is unconditional. Example: \"Only when invoice total exceeds $10,000\""
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "description": "Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: \"Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval.\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "exceptions": {
        -            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        -            "items": {
        -              "properties": {
        -                "exception": {
        -                  "description": "A distinct failure mode that can happen at this step.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "enum": [
        -                        "rare",
        -                        "occasional",
        -                        "frequent"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        -                },
        -                "handling": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How the team responds to this exception. Null when the response was not documented."
        -                },
        -                "id": {
        -                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "exception",
        -                "handling",
        -                "frequency"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN task subtype. \"user\" (human work), \"service\" (automated/API call), \"send\"/\"receive\" (messaging), \"manual\" (offline physical work), \"businessRule\" (rule engine), \"script\" (code execution).",
        -            "enum": [
        -              "user",
        -              "service",
        -              "send",
        -              "receive",
        -              "manual",
        -              "businessRule",
        -              "script"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "task",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "description": "Why this step exists in the process — its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: \"Catches mispriced line items before they reach the customer and prevents downstream credit notes.\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting this step's existence and details. At least one source is required — every step must trace back to something in the captures.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exceptions",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      },
        -      {
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "description": "Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as \"unknown\" via a read-side preprocess; producers should write a real condition string going forward.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "description": "Full prose describing the decision logic at this gateway.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "exceptions": {
        -            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        -            "items": {
        -              "properties": {
        -                "exception": {
        -                  "description": "A distinct failure mode that can happen at this step.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "frequency": {
        -                  "anyOf": [
        -                    {
        -                      "enum": [
        -                        "rare",
        -                        "occasional",
        -                        "frequent"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        -                },
        -                "handling": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "How the team responds to this exception. Null when the response was not documented."
        -                },
        -                "id": {
        -                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "id",
        -                "exception",
        -                "handling",
        -                "frequency"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN gateway subtype. \"exclusive\" (XOR — exactly one branch taken), \"parallel\" (AND — all branches taken), \"inclusive\" (OR — one or more branches taken).",
        -            "enum": [
        -              "exclusive",
        -              "parallel",
        -              "inclusive"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "gateway",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "description": "Why this branching decision exists in the process.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting the decision criteria.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exceptions",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      }
        -    ]
        -  },
        -  {
        -    "oneOf": [
        -      {
        -        "additionalProperties": false,
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Always null on events; included for shape compatibility across variants."
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional prose describing what happens at this event. May be null for structural markers."
        -          },
        -          "exception": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "handling": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN event subtype. \"start\" (entry trigger), \"end\" (terminal state), \"timer\" (time-based wait; title it with the duration, deadline, or cadence the captures give, e.g. \"Supplier reply: 2-3 days\"), \"message\" (external communication), \"escalation\" (route to higher authority).",
        -            "enum": [
        -              "start",
        -              "end",
        -              "timer",
        -              "message",
        -              "escalation"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "event",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional reason for the event's existence. May be null for structural markers."
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exception",
        -          "handling",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      },
        -      {
        -        "additionalProperties": false,
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Optional precondition that gates this task. Null when the task is unconditional. Example: \"Only when invoice total exceeds $10,000\""
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "description": "Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: \"Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval.\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "exception": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "handling": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN task subtype. \"user\" (human work), \"service\" (automated/API call), \"send\"/\"receive\" (messaging), \"manual\" (offline physical work), \"businessRule\" (rule engine), \"script\" (code execution).",
        -            "enum": [
        -              "user",
        -              "service",
        -              "send",
        -              "receive",
        -              "manual",
        -              "businessRule",
        -              "script"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "task",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "description": "Why this step exists in the process — its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: \"Catches mispriced line items before they reach the customer and prevents downstream credit notes.\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting this step's existence and details. At least one source is required — every step must trace back to something in the captures.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exception",
        -          "handling",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      },
        -      {
        -        "additionalProperties": false,
        -        "properties": {
        -          "action": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        -          },
        -          "assumptions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        -          },
        -          "condition": {
        -            "description": "Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as \"unknown\" via a read-side preprocess; producers should write a real condition string going forward.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "confidence": {
        -            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        -            "enum": [
        -              "low",
        -              "medium",
        -              "high"
        -            ],
        -            "type": "string"
        -          },
        -          "dataObjects": {
        -            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        -            "items": {
        -              "properties": {
        -                "access": {
        -                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        -                  "enum": [
        -                    "read",
        -                    "write"
        -                  ],
        -                  "type": "string"
        -                },
        -                "name": {
        -                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "state": {
        -                  "anyOf": [
        -                    {
        -                      "minLength": 1,
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        -                }
        -              },
        -              "required": [
        -                "name",
        -                "state",
        -                "access"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "description": {
        -            "description": "Full prose describing the decision logic at this gateway.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "exception": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        -          },
        -          "extraCaptureNeeded": {
        -            "anyOf": [
        -              {
        -                "properties": {
        -                  "gap": {
        -                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "id": {
        -                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        -                    "format": "uuid",
        -                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                    "type": "string"
        -                  },
        -                  "proposal": {
        -                    "anyOf": [
        -                      {
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      {
        -                        "type": "null"
        -                      }
        -                    ],
        -                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        -                  }
        -                },
        -                "required": [
        -                  "id",
        -                  "gap"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ]
        -          },
        -          "handling": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        -          },
        -          "id": {
        -            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        -          },
        -          "laneId": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        -          },
        -          "linkedAgentId": {
        -            "anyOf": [
        -              {
        -                "format": "uuid",
        -                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        -          },
        -          "nodeSubtype": {
        -            "description": "BPMN gateway subtype. \"exclusive\" (XOR — exactly one branch taken), \"parallel\" (AND — all branches taken), \"inclusive\" (OR — one or more branches taken).",
        -            "enum": [
        -              "exclusive",
        -              "parallel",
        -              "inclusive"
        -            ],
        -            "type": "string"
        -          },
        -          "nodeType": {
        -            "const": "gateway",
        -            "type": "string"
        -          },
        -          "openQuestions": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        -          },
        -          "output": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        -          },
        -          "pool": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        -          },
        -          "rationale": {
        -            "description": "Why this branching decision exists in the process.",
        -            "minLength": 1,
        -            "type": "string"
        -          },
        -          "readiness": {
        -            "anyOf": [
        -              {
        -                "enum": [
        -                  "low",
        -                  "medium",
        -                  "high"
        -                ],
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        -          },
        -          "readinessRationale": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        -          },
        -          "role": {
        -            "anyOf": [
        -              {
        -                "minLength": 1,
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        -          },
        -          "sources": {
        -            "description": "Evidence supporting the decision criteria.",
        -            "items": {
        -              "properties": {
        -                "attribution": {
        -                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "captureId": {
        -                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "evidenceId": {
        -                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "excerpt": {
        -                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                },
        -                "locator": {
        -                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        -                  "oneOf": [
        -                    {
        -                      "properties": {
        -                        "messageIndex": {
        -                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "timestampMs": {
        -                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "transcript_message",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "messageIndex"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "endLine": {
        -                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "endOffset": {
        -                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "pageNumber": {
        -                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startLine": {
        -                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        -                          "exclusiveMinimum": 0,
        -                          "maximum": 9007199254740991,
        -                          "type": "integer"
        -                        },
        -                        "startOffset": {
        -                          "description": "Zero-based character offset into the stored capture text.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "document_text_range",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "startOffset",
        -                        "endOffset"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "elementId": {
        -                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "elementType": {
        -                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "name": {
        -                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "bpmn_element",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "elementId"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "timestampMs": {
        -                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        -                          "maximum": 9007199254740991,
        -                          "minimum": 0,
        -                          "type": "integer"
        -                        },
        -                        "type": {
        -                          "const": "screenshare_frame",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type",
        -                        "timestampMs"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "type": {
        -                          "const": "manual",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    },
        -                    {
        -                      "properties": {
        -                        "reason": {
        -                          "minLength": 1,
        -                          "type": "string"
        -                        },
        -                        "type": {
        -                          "const": "unresolved",
        -                          "type": "string"
        -                        }
        -                      },
        -                      "required": [
        -                        "type"
        -                      ],
        -                      "type": "object"
        -                    }
        -                  ]
        -                },
        -                "resolutionStatus": {
        -                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        -                  "enum": [
        -                    "resolved",
        -                    "unresolved",
        -                    "legacy",
        -                    "manual"
        -                  ],
        -                  "type": "string"
        -                },
        -                "sourceConfidence": {
        -                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        -                  "enum": [
        -                    "low",
        -                    "medium",
        -                    "high"
        -                  ],
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "attribution",
        -                "excerpt"
        -              ],
        -              "type": "object"
        -            },
        -            "minItems": 1,
        -            "type": "array"
        -          },
        -          "system": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        -          },
        -          "targetSteps": {
        -            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        -            "items": {
        -              "properties": {
        -                "isDefault": {
        -                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        -                  "type": "boolean"
        -                },
        -                "label": {
        -                  "anyOf": [
        -                    {
        -                      "type": "string"
        -                    },
        -                    {
        -                      "type": "null"
        -                    }
        -                  ],
        -                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        -                },
        -                "stepId": {
        -                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        -                  "minLength": 1,
        -                  "type": "string"
        -                }
        -              },
        -              "required": [
        -                "stepId",
        -                "label",
        -                "isDefault"
        -              ],
        -              "type": "object"
        -            },
        -            "type": "array"
        -          },
        -          "title": {
        -            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        -            "minLength": 1,
        -            "type": "string"
        -          }
        -        },
        -        "required": [
        -          "id",
        -          "targetSteps",
        -          "title",
        -          "action",
        -          "role",
        -          "system",
        -          "input",
        -          "output",
        -          "exception",
        -          "handling",
        -          "assumptions",
        -          "openQuestions",
        -          "confidence",
        -          "nodeType",
        -          "nodeSubtype",
        -          "description",
        -          "rationale",
        -          "sources",
        -          "condition"
        -        ],
        -        "type": "object"
        -      }
        -    ]
        -  }
        -]New value: +[
        +  {
        +    "oneOf": [
        +      {
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Always null on events; included for shape compatibility across variants."
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "conflicts": {
        +            "items": {
        +              "properties": {
        +                "id": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "mappedVersionIndex": {
        +                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        +                  "maximum": 9007199254740991,
        +                  "minimum": 0,
        +                  "type": "integer"
        +                },
        +                "question": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "versions": {
        +                  "items": {
        +                    "properties": {
        +                      "attribution": {
        +                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "captureId": {
        +                        "format": "uuid",
        +                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                        "type": "string"
        +                      },
        +                      "evidenceId": {
        +                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "excerpt": {
        +                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "locator": {
        +                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                        "oneOf": [
        +                          {
        +                            "properties": {
        +                              "messageIndex": {
        +                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "timestampMs": {
        +                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "transcript_message",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "messageIndex"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "endLine": {
        +                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "endOffset": {
        +                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "pageNumber": {
        +                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startLine": {
        +                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startOffset": {
        +                                "description": "Zero-based character offset into the stored capture text.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "document_text_range",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "startOffset",
        +                              "endOffset"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "elementId": {
        +                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "elementType": {
        +                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "name": {
        +                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "bpmn_element",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "elementId"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "timestampMs": {
        +                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "screenshare_frame",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "timestampMs"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "type": {
        +                                "const": "manual",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "reason": {
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "unresolved",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        ]
        +                      },
        +                      "resolutionStatus": {
        +                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                        "enum": [
        +                          "resolved",
        +                          "unresolved",
        +                          "legacy",
        +                          "manual"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "sourceConfidence": {
        +                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                        "enum": [
        +                          "low",
        +                          "medium",
        +                          "high"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "title": {
        +                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "attribution",
        +                      "excerpt",
        +                      "captureId"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 2,
        +                  "type": "array"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "question",
        +                "versions"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional prose describing what happens at this event. May be null for structural markers."
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exceptions": {
        +            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        +            "items": {
        +              "properties": {
        +                "exception": {
        +                  "description": "A distinct failure mode that can happen at this step.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "enum": [
        +                        "rare",
        +                        "occasional",
        +                        "frequent"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        +                },
        +                "handling": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How the team responds to this exception. Null when the response was not documented."
        +                },
        +                "id": {
        +                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "exception",
        +                "handling",
        +                "frequency"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN event subtype. \"start\" (entry trigger), \"end\" (terminal state), \"timer\" (time-based wait; title it with the duration, deadline, or cadence the captures give, e.g. \"Supplier reply: 2-3 days\"), \"message\" (external communication), \"escalation\" (route to higher authority).",
        +            "enum": [
        +              "start",
        +              "end",
        +              "timer",
        +              "message",
        +              "escalation"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "event",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional reason for the event's existence. May be null for structural markers."
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exceptions",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional precondition that gates this task. Null when the task is unconditional. Example: \"Only when invoice total exceeds $10,000\""
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "conflicts": {
        +            "items": {
        +              "properties": {
        +                "id": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "mappedVersionIndex": {
        +                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        +                  "maximum": 9007199254740991,
        +                  "minimum": 0,
        +                  "type": "integer"
        +                },
        +                "question": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "versions": {
        +                  "items": {
        +                    "properties": {
        +                      "attribution": {
        +                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "captureId": {
        +                        "format": "uuid",
        +                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                        "type": "string"
        +                      },
        +                      "evidenceId": {
        +                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "excerpt": {
        +                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "locator": {
        +                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                        "oneOf": [
        +                          {
        +                            "properties": {
        +                              "messageIndex": {
        +                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "timestampMs": {
        +                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "transcript_message",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "messageIndex"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "endLine": {
        +                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "endOffset": {
        +                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "pageNumber": {
        +                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startLine": {
        +                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startOffset": {
        +                                "description": "Zero-based character offset into the stored capture text.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "document_text_range",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "startOffset",
        +                              "endOffset"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "elementId": {
        +                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "elementType": {
        +                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "name": {
        +                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "bpmn_element",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "elementId"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "timestampMs": {
        +                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "screenshare_frame",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "timestampMs"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "type": {
        +                                "const": "manual",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "reason": {
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "unresolved",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        ]
        +                      },
        +                      "resolutionStatus": {
        +                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                        "enum": [
        +                          "resolved",
        +                          "unresolved",
        +                          "legacy",
        +                          "manual"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "sourceConfidence": {
        +                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                        "enum": [
        +                          "low",
        +                          "medium",
        +                          "high"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "title": {
        +                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "attribution",
        +                      "excerpt",
        +                      "captureId"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 2,
        +                  "type": "array"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "question",
        +                "versions"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: \"Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval.\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exceptions": {
        +            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        +            "items": {
        +              "properties": {
        +                "exception": {
        +                  "description": "A distinct failure mode that can happen at this step.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "enum": [
        +                        "rare",
        +                        "occasional",
        +                        "frequent"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        +                },
        +                "handling": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How the team responds to this exception. Null when the response was not documented."
        +                },
        +                "id": {
        +                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "exception",
        +                "handling",
        +                "frequency"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN task subtype. \"user\" (human work), \"service\" (automated/API call), \"send\"/\"receive\" (messaging), \"manual\" (offline physical work), \"businessRule\" (rule engine), \"script\" (code execution).",
        +            "enum": [
        +              "user",
        +              "service",
        +              "send",
        +              "receive",
        +              "manual",
        +              "businessRule",
        +              "script"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "task",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "description": "Why this step exists in the process — its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: \"Catches mispriced line items before they reach the customer and prevents downstream credit notes.\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting this step's existence and details. At least one source is required — every step must trace back to something in the captures.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exceptions",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "description": "Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as \"unknown\" via a read-side preprocess; producers should write a real condition string going forward.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "conflicts": {
        +            "items": {
        +              "properties": {
        +                "id": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "mappedVersionIndex": {
        +                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        +                  "maximum": 9007199254740991,
        +                  "minimum": 0,
        +                  "type": "integer"
        +                },
        +                "question": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "versions": {
        +                  "items": {
        +                    "properties": {
        +                      "attribution": {
        +                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "captureId": {
        +                        "format": "uuid",
        +                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                        "type": "string"
        +                      },
        +                      "evidenceId": {
        +                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "excerpt": {
        +                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "locator": {
        +                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                        "oneOf": [
        +                          {
        +                            "properties": {
        +                              "messageIndex": {
        +                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "timestampMs": {
        +                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "transcript_message",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "messageIndex"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "endLine": {
        +                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "endOffset": {
        +                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "pageNumber": {
        +                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startLine": {
        +                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startOffset": {
        +                                "description": "Zero-based character offset into the stored capture text.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "document_text_range",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "startOffset",
        +                              "endOffset"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "elementId": {
        +                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "elementType": {
        +                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "name": {
        +                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "bpmn_element",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "elementId"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "timestampMs": {
        +                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "screenshare_frame",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "timestampMs"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "type": {
        +                                "const": "manual",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "reason": {
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "unresolved",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        ]
        +                      },
        +                      "resolutionStatus": {
        +                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                        "enum": [
        +                          "resolved",
        +                          "unresolved",
        +                          "legacy",
        +                          "manual"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "sourceConfidence": {
        +                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                        "enum": [
        +                          "low",
        +                          "medium",
        +                          "high"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "title": {
        +                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "attribution",
        +                      "excerpt",
        +                      "captureId"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 2,
        +                  "type": "array"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "question",
        +                "versions"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose describing the decision logic at this gateway.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exceptions": {
        +            "description": "Distinct failure modes for this step in display order. Use an empty array when none are documented. Preserve each id when the same exception is edited or regenerated.",
        +            "items": {
        +              "properties": {
        +                "exception": {
        +                  "description": "A distinct failure mode that can happen at this step.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "enum": [
        +                        "rare",
        +                        "occasional",
        +                        "frequent"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Observed frequency. Null unless evidence explicitly supports rare, occasional, or frequent."
        +                },
        +                "handling": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How the team responds to this exception. Null when the response was not documented."
        +                },
        +                "id": {
        +                  "description": "Stable identifier for this exception. Preserve it when the same exception is edited or regenerated. Example: \"exception-po-mismatch\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "exception",
        +                "handling",
        +                "frequency"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN gateway subtype. \"exclusive\" (XOR — exactly one branch taken), \"parallel\" (AND — all branches taken), \"inclusive\" (OR — one or more branches taken).",
        +            "enum": [
        +              "exclusive",
        +              "parallel",
        +              "inclusive"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "gateway",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "description": "Why this branching decision exists in the process.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting the decision criteria.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exceptions",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      }
        +    ]
        +  },
        +  {
        +    "oneOf": [
        +      {
        +        "additionalProperties": false,
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Always null on events; included for shape compatibility across variants."
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "conflicts": {
        +            "items": {
        +              "properties": {
        +                "id": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "mappedVersionIndex": {
        +                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        +                  "maximum": 9007199254740991,
        +                  "minimum": 0,
        +                  "type": "integer"
        +                },
        +                "question": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "versions": {
        +                  "items": {
        +                    "properties": {
        +                      "attribution": {
        +                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "captureId": {
        +                        "format": "uuid",
        +                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                        "type": "string"
        +                      },
        +                      "evidenceId": {
        +                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "excerpt": {
        +                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "locator": {
        +                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                        "oneOf": [
        +                          {
        +                            "properties": {
        +                              "messageIndex": {
        +                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "timestampMs": {
        +                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "transcript_message",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "messageIndex"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "endLine": {
        +                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "endOffset": {
        +                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "pageNumber": {
        +                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startLine": {
        +                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startOffset": {
        +                                "description": "Zero-based character offset into the stored capture text.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "document_text_range",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "startOffset",
        +                              "endOffset"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "elementId": {
        +                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "elementType": {
        +                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "name": {
        +                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "bpmn_element",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "elementId"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "timestampMs": {
        +                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "screenshare_frame",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "timestampMs"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "type": {
        +                                "const": "manual",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "reason": {
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "unresolved",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        ]
        +                      },
        +                      "resolutionStatus": {
        +                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                        "enum": [
        +                          "resolved",
        +                          "unresolved",
        +                          "legacy",
        +                          "manual"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "sourceConfidence": {
        +                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                        "enum": [
        +                          "low",
        +                          "medium",
        +                          "high"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "title": {
        +                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "attribution",
        +                      "excerpt",
        +                      "captureId"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 2,
        +                  "type": "array"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "question",
        +                "versions"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional prose describing what happens at this event. May be null for structural markers."
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exception": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "handling": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN event subtype. \"start\" (entry trigger), \"end\" (terminal state), \"timer\" (time-based wait; title it with the duration, deadline, or cadence the captures give, e.g. \"Supplier reply: 2-3 days\"), \"message\" (external communication), \"escalation\" (route to higher authority).",
        +            "enum": [
        +              "start",
        +              "end",
        +              "timer",
        +              "message",
        +              "escalation"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "event",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional reason for the event's existence. May be null for structural markers."
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting this event. Empty array allowed (structural markers carry no evidence); non-empty values must follow the source schema.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exception",
        +          "handling",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Optional precondition that gates this task. Null when the task is unconditional. Example: \"Only when invoice total exceeds $10,000\""
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "conflicts": {
        +            "items": {
        +              "properties": {
        +                "id": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "mappedVersionIndex": {
        +                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        +                  "maximum": 9007199254740991,
        +                  "minimum": 0,
        +                  "type": "integer"
        +                },
        +                "question": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "versions": {
        +                  "items": {
        +                    "properties": {
        +                      "attribution": {
        +                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "captureId": {
        +                        "format": "uuid",
        +                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                        "type": "string"
        +                      },
        +                      "evidenceId": {
        +                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "excerpt": {
        +                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "locator": {
        +                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                        "oneOf": [
        +                          {
        +                            "properties": {
        +                              "messageIndex": {
        +                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "timestampMs": {
        +                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "transcript_message",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "messageIndex"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "endLine": {
        +                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "endOffset": {
        +                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "pageNumber": {
        +                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startLine": {
        +                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startOffset": {
        +                                "description": "Zero-based character offset into the stored capture text.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "document_text_range",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "startOffset",
        +                              "endOffset"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "elementId": {
        +                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "elementType": {
        +                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "name": {
        +                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "bpmn_element",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "elementId"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "timestampMs": {
        +                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "screenshare_frame",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "timestampMs"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "type": {
        +                                "const": "manual",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "reason": {
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "unresolved",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        ]
        +                      },
        +                      "resolutionStatus": {
        +                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                        "enum": [
        +                          "resolved",
        +                          "unresolved",
        +                          "legacy",
        +                          "manual"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "sourceConfidence": {
        +                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                        "enum": [
        +                          "low",
        +                          "medium",
        +                          "high"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "title": {
        +                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "attribution",
        +                      "excerpt",
        +                      "captureId"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 2,
        +                  "type": "array"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "question",
        +                "versions"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose paragraph describing what happens in this step in natural language. Used for documentation reconstruction. Example: \"Finance reviews the invoice in NetSuite, checking line item accuracy and matching against the purchase order before flagging for approval.\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exception": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "handling": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN task subtype. \"user\" (human work), \"service\" (automated/API call), \"send\"/\"receive\" (messaging), \"manual\" (offline physical work), \"businessRule\" (rule engine), \"script\" (code execution).",
        +            "enum": [
        +              "user",
        +              "service",
        +              "send",
        +              "receive",
        +              "manual",
        +              "businessRule",
        +              "script"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "task",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "description": "Why this step exists in the process — its purpose or business reason. Used by downstream agents to assess whether the step is essential or removable. Example: \"Catches mispriced line items before they reach the customer and prevents downstream credit notes.\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting this step's existence and details. At least one source is required — every step must trace back to something in the captures.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exception",
        +          "handling",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      },
        +      {
        +        "additionalProperties": false,
        +        "properties": {
        +          "action": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Verb-led one-liner summarizing the concrete action performed. Example: \"Reviews invoice line items in NetSuite against the purchase order.\""
        +          },
        +          "assumptions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Assumptions the LLM made when extracting this step that were not directly stated in captures. Null if none. Used by verification agents to flag risky inferences. Example: [\"Invoices are reviewed within 24 hours of receipt\"]"
        +          },
        +          "condition": {
        +            "description": "Decision criteria evaluated at this gateway. BPMN requires this on every branching gateway. Existing rows persisted with null/empty values parse as \"unknown\" via a read-side preprocess; producers should write a real condition string going forward.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "confidence": {
        +            "description": "Confidence in the accuracy of this step given evidence quality and completeness. \"high\" = directly stated by multiple sources, \"medium\" = stated by one source or inferred from strong signals, \"low\" = inferred with significant assumptions.",
        +            "enum": [
        +              "low",
        +              "medium",
        +              "high"
        +            ],
        +            "type": "string"
        +          },
        +          "conflicts": {
        +            "items": {
        +              "properties": {
        +                "id": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "mappedVersionIndex": {
        +                  "description": "Zero-based index in versions of the account represented by this step in the current diagram. Omit when unknown. Update or clear it when the diagram or versions change. This records the diagram content, not a resolved conflict.",
        +                  "maximum": 9007199254740991,
        +                  "minimum": 0,
        +                  "type": "integer"
        +                },
        +                "question": {
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "versions": {
        +                  "items": {
        +                    "properties": {
        +                      "attribution": {
        +                        "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "captureId": {
        +                        "format": "uuid",
        +                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                        "type": "string"
        +                      },
        +                      "evidenceId": {
        +                        "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "excerpt": {
        +                        "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "locator": {
        +                        "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                        "oneOf": [
        +                          {
        +                            "properties": {
        +                              "messageIndex": {
        +                                "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "timestampMs": {
        +                                "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "transcript_message",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "messageIndex"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "endLine": {
        +                                "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "endOffset": {
        +                                "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "pageNumber": {
        +                                "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startLine": {
        +                                "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                                "exclusiveMinimum": 0,
        +                                "maximum": 9007199254740991,
        +                                "type": "integer"
        +                              },
        +                              "startOffset": {
        +                                "description": "Zero-based character offset into the stored capture text.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "document_text_range",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "startOffset",
        +                              "endOffset"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "elementId": {
        +                                "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "elementType": {
        +                                "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "name": {
        +                                "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "bpmn_element",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "elementId"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "timestampMs": {
        +                                "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                                "maximum": 9007199254740991,
        +                                "minimum": 0,
        +                                "type": "integer"
        +                              },
        +                              "type": {
        +                                "const": "screenshare_frame",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type",
        +                              "timestampMs"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "type": {
        +                                "const": "manual",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          },
        +                          {
        +                            "properties": {
        +                              "reason": {
        +                                "minLength": 1,
        +                                "type": "string"
        +                              },
        +                              "type": {
        +                                "const": "unresolved",
        +                                "type": "string"
        +                              }
        +                            },
        +                            "required": [
        +                              "type"
        +                            ],
        +                            "type": "object"
        +                          }
        +                        ]
        +                      },
        +                      "resolutionStatus": {
        +                        "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                        "enum": [
        +                          "resolved",
        +                          "unresolved",
        +                          "legacy",
        +                          "manual"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "sourceConfidence": {
        +                        "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                        "enum": [
        +                          "low",
        +                          "medium",
        +                          "high"
        +                        ],
        +                        "type": "string"
        +                      },
        +                      "title": {
        +                        "description": "Short heading describing this account; the excerpt remains the exact source quote",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      }
        +                    },
        +                    "required": [
        +                      "attribution",
        +                      "excerpt",
        +                      "captureId"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "minItems": 2,
        +                  "type": "array"
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "question",
        +                "versions"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "dataObjects": {
        +            "description": "Documents or records this step reads or writes, such as an invoice, a purchase order, or a price list. The process map draws each distinct name and state once and links it to every step that lists it. Omit or use an empty array when the captures name none.",
        +            "items": {
        +              "properties": {
        +                "access": {
        +                  "description": "\"read\" when the step uses the object as input; \"write\" when the step creates or updates it.",
        +                  "enum": [
        +                    "read",
        +                    "write"
        +                  ],
        +                  "type": "string"
        +                },
        +                "name": {
        +                  "description": "Name of the document or record, as the captures call it. Use the exact same name on every step that touches the same object. Examples: \"Invoice\", \"Purchase order\", \"Price list\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "state": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "State the object is in at this step, only when the captures name one. Null otherwise. Examples: \"approved\", \"draft\", null"
        +                }
        +              },
        +              "required": [
        +                "name",
        +                "state",
        +                "access"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "description": {
        +            "description": "Full prose describing the decision logic at this gateway.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "effort": {
        +            "description": "Time each interviewee spends on this step, one entry per person per capture. Omit when no interviewee spoke to this step's time or frequency.",
        +            "items": {
        +              "properties": {
        +                "basis": {
        +                  "description": "\"stated\" = the person gave the number; \"estimated\" = they gave or accepted a rough guess when pressed; \"unknown\" = they were asked but gave no figure, so timeSpent and frequency are both null.",
        +                  "enum": [
        +                    "stated",
        +                    "estimated",
        +                    "unknown"
        +                  ],
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id of the interview the figure came from. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim quote the figure comes from. Example: \"Probably two hours every morning, more at month end.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "frequency": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "count": {
        +                          "description": "How many times the work happens per period. Example: 40",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the count covers. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "count",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "How often the work happens for this person. Null unless they gave a count."
        +                },
        +                "person": {
        +                  "description": "Who reported this effort, matching the source attribution. Example: \"Anna, AP Clerk\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "timeSpent": {
        +                  "anyOf": [
        +                    {
        +                      "properties": {
        +                        "hours": {
        +                          "description": "Hours this person spends on the work per period. Use one best value; for a range (\"1 to 2 hours\") use the midpoint and keep the range in excerpt. Example: 2",
        +                          "exclusiveMinimum": 0,
        +                          "type": "number"
        +                        },
        +                        "period": {
        +                          "description": "Period the hours cover. Example: \"day\"",
        +                          "enum": [
        +                            "day",
        +                            "week",
        +                            "month"
        +                          ],
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "hours",
        +                        "period"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Time this person spends on the work. Null when they gave no time figure; whether they were asked is carried by basis (\"unknown\" when asked and both figures are null)."
        +                }
        +              },
        +              "required": [
        +                "person",
        +                "timeSpent",
        +                "frequency",
        +                "basis",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "exception": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Known exceptions, errors, or failure modes observed in the captures for this step. Null when none were mentioned. Example: \"Customer disputes line items or PO number does not match\""
        +          },
        +          "extraCaptureNeeded": {
        +            "anyOf": [
        +              {
        +                "properties": {
        +                  "gap": {
        +                    "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "id": {
        +                    "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                    "format": "uuid",
        +                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                    "type": "string"
        +                  },
        +                  "proposal": {
        +                    "anyOf": [
        +                      {
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      {
        +                        "type": "null"
        +                      }
        +                    ],
        +                    "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                  }
        +                },
        +                "required": [
        +                  "id",
        +                  "gap"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ]
        +          },
        +          "extraCaptureNeeds": {
        +            "items": {
        +              "properties": {
        +                "gap": {
        +                  "description": "Plain-language description of what about this step is unknown or under-specified, blocking automation. One short sentence. Example: \"We don't know which fields the AP analyst copies from the invoice into NetSuite.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "id": {
        +                  "description": "Id of the `clarity_proposal_extra_capture_request` row this slot points at. Created server-side by the agent after the LLM call; the LLM never produces this value.",
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                  "type": "string"
        +                },
        +                "proposal": {
        +                  "anyOf": [
        +                    {
        +                      "minLength": 1,
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "What the new capture should include in order to resolve the gap — concrete actions, screens, or decisions the user should walk through. Optional: omit when no specific proposal can be inferred. Example: \"Walk through reviewing one invoice in NetSuite end-to-end while narrating each field you check.\""
        +                }
        +              },
        +              "required": [
        +                "id",
        +                "gap"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "handling": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "How exceptions or escalations are handled — escalation path, fallback action, or retry strategy. Null when no exception or no handling described. Example: \"Escalate to AP manager via email and pause processing until resolved\""
        +          },
        +          "id": {
        +            "description": "Stable identifier for the step. Referenced by targetSteps[].stepId and by postprocessing agents annotating specific steps. Example: \"step-review-invoice\"",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Information or artifacts required to start this step. Null on start events or steps with no preconditions. Example: \"Invoice PDF and matching purchase order number\""
        +          },
        +          "laneId": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the lane in the snapshot's lanes array that performs this step. Null when the step has no role. The server keeps it in step with `role`."
        +          },
        +          "linkedAgentId": {
        +            "anyOf": [
        +              {
        +                "format": "uuid",
        +                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$",
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Id of the Duvo Agent that performs this step. Set by a person in edit mode, never by a generating or postprocessing agent; the save route rejects an id that is not a live Agent on the process's team."
        +          },
        +          "nodeSubtype": {
        +            "description": "BPMN gateway subtype. \"exclusive\" (XOR — exactly one branch taken), \"parallel\" (AND — all branches taken), \"inclusive\" (OR — one or more branches taken).",
        +            "enum": [
        +              "exclusive",
        +              "parallel",
        +              "inclusive"
        +            ],
        +            "type": "string"
        +          },
        +          "nodeType": {
        +            "const": "gateway",
        +            "type": "string"
        +          },
        +          "openQuestions": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Specific gaps in understanding that a follow-up capture should address. Null if none. Drives the next interview or document request. Example: [\"Is there a backup approver when the AP manager is out of office?\"]"
        +          },
        +          "output": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "What this step produces or updates. Null on pure waits or events that emit nothing. Example: \"Approved invoice record in NetSuite with reviewer signature\""
        +          },
        +          "pool": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "The organization or party outside the process owner's own organization that performs this step, such as \"Supplier\", \"Customer\", \"Bank\", or \"Tax authority\". The process map draws each party as its own pool, with its roles as lanes inside it. Null for every step the process owner's own organization performs, which is most of them. Use one spelling per party, and give every step of one role the same pool."
        +          },
        +          "rationale": {
        +            "description": "Why this branching decision exists in the process.",
        +            "minLength": 1,
        +            "type": "string"
        +          },
        +          "readiness": {
        +            "anyOf": [
        +              {
        +                "enum": [
        +                  "low",
        +                  "medium",
        +                  "high"
        +                ],
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Automation-readiness rating for this step. \"high\" = fully automatable today, \"medium\" = partially automatable or needs minor changes, \"low\" = blocked by manual review, judgement, or missing data."
        +          },
        +          "readinessRationale": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "One-sentence justification for the readiness rating, citing the specific signals that drove the choice. Example: \"Requires human judgement on edge cases that are not documented in the captures.\""
        +          },
        +          "role": {
        +            "anyOf": [
        +              {
        +                "minLength": 1,
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "Performer of this step — the specific job title, team, or system. Use \"Duvo\" for automated actions and \"System\" for system-triggered steps. The process map draws one lane per distinct role, so decide the process's roles once and give every step a role performs the exact same text; never combine two roles in one value such as \"Buyer or Commercial\". Examples: \"Finance Analyst\", \"Sales Operations\", \"Duvo\", \"System\""
        +          },
        +          "sources": {
        +            "description": "Evidence supporting the decision criteria.",
        +            "items": {
        +              "properties": {
        +                "attribution": {
        +                  "description": "Human-readable source label identifying who or what the evidence comes from. Examples: \"Anna (sales interview)\", \"Onboarding SOP §3.2\", \"Slack #ops 2024-06-12\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "captureId": {
        +                  "description": "Durable clarity_capture id for this source. Use app-owned ids from the evidence index, never sandbox file paths.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "evidenceId": {
        +                  "description": "Stable id of the evidence unit from /workspace/captures/evidence-index.json when generation used that index.",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "excerpt": {
        +                  "description": "Verbatim supporting text quoted from the capture, document, or transcript. Example: \"We always wait for finance to sign off before sending the invoice.\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                },
        +                "locator": {
        +                  "description": "Durable in-capture location for the excerpt. Missing means legacy free-text source; unresolved means a structured citation was attempted but could not be resolved.",
        +                  "oneOf": [
        +                    {
        +                      "properties": {
        +                        "messageIndex": {
        +                          "description": "Zero-based index into the capture transcript message array. This is the durable key; timestampMs is only supplemental.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "timestampMs": {
        +                          "description": "Optional epoch-millisecond timestamp for the transcript message when the capture supplied one.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "transcript_message",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "messageIndex"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "endLine": {
        +                          "description": "Optional one-based line number where the cited text ends on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "endOffset": {
        +                          "description": "Exclusive character offset into the stored capture text. Must be greater than startOffset.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "pageNumber": {
        +                          "description": "Optional one-based PDF page number when the stored capture has page metadata.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startLine": {
        +                          "description": "Optional one-based line number where the cited text starts on pageNumber.",
        +                          "exclusiveMinimum": 0,
        +                          "maximum": 9007199254740991,
        +                          "type": "integer"
        +                        },
        +                        "startOffset": {
        +                          "description": "Zero-based character offset into the stored capture text.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "document_text_range",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "startOffset",
        +                        "endOffset"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "elementId": {
        +                          "description": "BPMN XML element id within an uploaded .bpmn document.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "elementType": {
        +                          "description": "Optional BPMN element type as parsed from the XML, for example \"bpmn:UserTask\" or \"bpmn:ExclusiveGateway\".",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "name": {
        +                          "description": "Optional BPMN element name as parsed from the XML. The element id is the durable key.",
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "bpmn_element",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "elementId"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "timestampMs": {
        +                          "description": "Epoch-millisecond frame timestamp matching a screenshare frame filename.",
        +                          "maximum": 9007199254740991,
        +                          "minimum": 0,
        +                          "type": "integer"
        +                        },
        +                        "type": {
        +                          "const": "screenshare_frame",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type",
        +                        "timestampMs"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "type": {
        +                          "const": "manual",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    },
        +                    {
        +                      "properties": {
        +                        "reason": {
        +                          "minLength": 1,
        +                          "type": "string"
        +                        },
        +                        "type": {
        +                          "const": "unresolved",
        +                          "type": "string"
        +                        }
        +                      },
        +                      "required": [
        +                        "type"
        +                      ],
        +                      "type": "object"
        +                    }
        +                  ]
        +                },
        +                "resolutionStatus": {
        +                  "description": "Resolution status for the structured source link. Legacy sources may omit this field.",
        +                  "enum": [
        +                    "resolved",
        +                    "unresolved",
        +                    "legacy",
        +                    "manual"
        +                  ],
        +                  "type": "string"
        +                },
        +                "sourceConfidence": {
        +                  "description": "Confidence in this individual source citation. \"high\" = direct quote at the locator, \"medium\" = strong nearby evidence, \"low\" = weak or inferred support.",
        +                  "enum": [
        +                    "low",
        +                    "medium",
        +                    "high"
        +                  ],
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "attribution",
        +                "excerpt"
        +              ],
        +              "type": "object"
        +            },
        +            "minItems": 1,
        +            "type": "array"
        +          },
        +          "system": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "description": "System, tool, or application used to perform this step. Null when the step is purely manual or is a decision/event with no associated tool. Examples: \"NetSuite\", \"Gmail\", \"Excel\", null"
        +          },
        +          "targetSteps": {
        +            "description": "Outgoing BPMN edges from this step. Empty array only on end events. Exclusive and inclusive gateways that branch must have ≥2 entries with exactly one isDefault: true; a merge gateway (≥2 incoming paths) has exactly 1 entry.",
        +            "items": {
        +              "properties": {
        +                "isDefault": {
        +                  "description": "True on exactly one outgoing edge of a branching exclusive or inclusive gateway, marking the fallback taken when no other condition matches. False on all other edges, including the single edge leaving a merge gateway.",
        +                  "type": "boolean"
        +                },
        +                "label": {
        +                  "anyOf": [
        +                    {
        +                      "type": "string"
        +                    },
        +                    {
        +                      "type": "null"
        +                    }
        +                  ],
        +                  "description": "Human-readable label shown on the BPMN edge. For gateways, the outcome answer; for default flows, \"Otherwise\"; for an edge into another role's lane or another party's pool, what is handed over and how. Examples: \"Approved\", \"> $5k\", \"Otherwise\", \"Signed contract, by email\""
        +                },
        +                "stepId": {
        +                  "description": "Id of the step this edge points to. Must match an existing step.id in the same steps array. Example: \"step-review-invoice\"",
        +                  "minLength": 1,
        +                  "type": "string"
        +                }
        +              },
        +              "required": [
        +                "stepId",
        +                "label",
        +                "isDefault"
        +              ],
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "title": {
        +            "description": "Required node label used in lists and BPMN node labels. Structural markers use defaults such as \"Start\" and \"End\".",
        +            "minLength": 1,
        +            "type": "string"
        +          }
        +        },
        +        "required": [
        +          "id",
        +          "targetSteps",
        +          "title",
        +          "action",
        +          "role",
        +          "system",
        +          "input",
        +          "output",
        +          "exception",
        +          "handling",
        +          "assumptions",
        +          "openQuestions",
        +          "confidence",
        +          "nodeType",
        +          "nodeSubtype",
        +          "description",
        +          "rationale",
        +          "sources",
        +          "condition"
        +        ],
        +        "type": "object"
        +      }
        +    ]
        +  }
        +]
    • ChangedupdateClarityTeamSettings1 field changed
      • changedInput schema / properties / language / enum
        Previous value: -[
        -  "cs",
        -  "de",
        -  "de-CH",
        -  "en",
        -  "en-GB",
        -  "es",
        -  "es-MX",
        -  "fr",
        -  "hu",
        -  "pl",
        -  "pt",
        -  "pt-BR",
        -  "sk",
        -  "sl",
        -  "th",
        -  "uk"
        -]New value: +[
        +  "cs",
        +  "de",
        +  "de-CH",
        +  "en",
        +  "en-GB",
        +  "es",
        +  "es-MX",
        +  "fr",
        +  "hu",
        +  "pl",
        +  "pt",
        +  "pt-BR",
        +  "sk",
        +  "sl",
        +  "th",
        +  "uk",
        +  "ar-EG",
        +  "ar-SA",
        +  "da-DK",
        +  "de-AT",
        +  "el-GR",
        +  "en-AU",
        +  "en-GB-scotland",
        +  "en-IE",
        +  "en-IN",
        +  "en-NG",
        +  "en-ZA",
        +  "es-AR",
        +  "fi-FI",
        +  "fr-BE",
        +  "fr-CA",
        +  "gsw-CH",
        +  "he-IL",
        +  "hi-IN",
        +  "hi-Latn-IN",
        +  "id-ID",
        +  "it-IT",
        +  "ja-JP",
        +  "ko-KR",
        +  "nb-NO",
        +  "nl-BE",
        +  "nl-NL",
        +  "ro-RO",
        +  "sv-SE",
        +  "tr-TR",
        +  "vi-VN",
        +  "yue-HK",
        +  "zh-Hans-CN",
        +  "zh-Hant-TW",
        +  "af-ZA",
        +  "ak-GH",
        +  "sq-AL",
        +  "am-ET",
        +  "hy-AM",
        +  "as-IN",
        +  "az-AZ",
        +  "eu-ES",
        +  "be-BY",
        +  "bn-BD",
        +  "bs-BA",
        +  "bg-BG",
        +  "my-MM",
        +  "ca-ES",
        +  "ceb-PH",
        +  "hr-HR",
        +  "et-EE",
        +  "fo-FO",
        +  "fil-PH",
        +  "gl-ES",
        +  "ka-GE",
        +  "gu-IN",
        +  "ha-NG",
        +  "is-IS",
        +  "ga-IE",
        +  "kn-IN",
        +  "kk-KZ",
        +  "km-KH",
        +  "rw-RW",
        +  "ku-TR",
        +  "ky-KG",
        +  "lo-LA",
        +  "lv-LV",
        +  "lt-LT",
        +  "mk-MK",
        +  "ms-MY",
        +  "ml-IN",
        +  "mt-MT",
        +  "mi-NZ",
        +  "mr-IN",
        +  "mn-MN",
        +  "ne-NP",
        +  "or-IN",
        +  "om-ET",
        +  "ps-AF",
        +  "fa-IR",
        +  "pa-IN",
        +  "qu-PE",
        +  "rm-CH",
        +  "ru-RU",
        +  "sr-RS",
        +  "sd-PK",
        +  "si-LK",
        +  "so-SO",
        +  "st-ZA",
        +  "sw-TZ",
        +  "tg-TJ",
        +  "ta-IN",
        +  "te-IN",
        +  "tn-ZA",
        +  "tk-TM",
        +  "ur-PK",
        +  "uz-UZ",
        +  "cy-GB",
        +  "fy-NL",
        +  "wo-SN",
        +  "yo-NG",
        +  "zu-ZA",
        +  "bn-IN",
        +  "ur-IN",
        +  "fr-CH",
        +  "it-CH",
        +  "de-BE",
        +  "sw-KE",
        +  "sw-UG",
        +  "ms-SG",
        +  "zh-Hans-SG",
        +  "ta-SG",
        +  "ta-LK",
        +  "yue-CN",
        +  "ar-IL",
        +  "ar-MA",
        +  "fr-MA",
        +  "sv-FI",
        +  "es-US",
        +  "ru-BY",
        +  "ru-KZ",
        +  "fa-AF",
        +  "ar-DZ",
        +  "fr-DZ",
        +  "ar-TN",
        +  "fr-TN",
        +  "ar-LY",
        +  "ar-SD",
        +  "ar-IQ",
        +  "ku-IQ",
        +  "ar-SY",
        +  "ar-JO",
        +  "ar-AE",
        +  "ar-QA",
        +  "ar-KW",
        +  "ar-OM",
        +  "ar-YE",
        +  "ar-LB",
        +  "fr-LB",
        +  "pt-AO",
        +  "pt-MZ",
        +  "es-CO",
        +  "es-PE",
        +  "es-CL",
        +  "es-VE",
        +  "es-EC",
        +  "es-BO",
        +  "qu-BO",
        +  "es-PY",
        +  "es-UY",
        +  "es-CU",
        +  "es-GT",
        +  "es-HN",
        +  "es-NI",
        +  "es-CR",
        +  "es-PA",
        +  "es-DO",
        +  "es-SV",
        +  "sr-ME",
        +  "fr-CD",
        +  "fr-CI",
        +  "fr-SN",
        +  "fr-ML",
        +  "fr-CM",
        +  "da-GL",
        +  "tn-BW",
        +  "af-NA",
        +  "el-CY",
        +  "tr-CY",
        +  "fr-LU",
        +  "de-LU",
        +  "en-CA",
        +  "en-NZ",
        +  "en-SG",
        +  "en-PH",
        +  "en-KE",
        +  "en-GH",
        +  "en-PK"
        +]
    • ChangedupdateConfigField1 field changed
      • addedInput schema / properties / expected_value
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/definitions/AutomationConfigJsonValue"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "description": "The current answer, as you read it and showed the user, not the new one (null if it was unanswered). If the answer has changed since, nothing is written and the call fails with 409; read the Policy again"
        +}
  14. 3 tool updates
    • ChangedcreateAgent2 fields changed
      • changedInput schema / properties / build / properties / config / properties / data / properties / models / properties / agent / properties / model / enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4-flash",
        -  "deepseek-v4.1-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4.1-flash",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max",
        +  "deepseek-v4-flash"
        +]
      • changedInput schema / properties / build / properties / config / properties / data / properties / models / properties / agent / properties / model / x-extensible-enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4-flash",
        -  "deepseek-v4.1-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4.1-flash",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max",
        +  "deepseek-v4-flash"
        +]
    • ChangedcreateAutomation2 fields changed
      • changedInput schema / properties / first_agent / properties / config / properties / data / properties / models / properties / agent / properties / model / enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4-flash",
        -  "deepseek-v4.1-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4.1-flash",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max",
        +  "deepseek-v4-flash"
        +]
      • changedInput schema / properties / first_agent / properties / config / properties / data / properties / models / properties / agent / properties / model / x-extensible-enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4-flash",
        -  "deepseek-v4.1-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4.1-flash",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max",
        +  "deepseek-v4-flash"
        +]
    • ChangedcreateRevision1 field changed
      • changedInput schema / properties / config / anyOf
        Previous value: -[
        -  {
        -    "properties": {
        -      "data": {
        -        "description": "Agent configuration payload",
        -        "properties": {
        -          "files": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Team files that should be available to the agent, each given as the relative file path returned in the `path` field of `GET /v2/teams/{teamId}/files` (for example `report.md` or `folder/doc.md`) — not the `id` field, which is a GCS object identifier."
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "items": {
        -                  "properties": {
        -                    "content": {
        -                      "anyOf": [
        -                        {
        -                          "type": "string"
        -                        },
        -                        {
        -                          "items": {
        -                            "anyOf": [
        -                              {
        -                                "properties": {
        -                                  "text": {
        -                                    "type": "string"
        -                                  },
        -                                  "type": {
        -                                    "const": "input_text",
        -                                    "type": "string"
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type",
        -                                  "text"
        -                                ],
        -                                "type": "object"
        -                              },
        -                              {
        -                                "properties": {
        -                                  "detail": {
        -                                    "anyOf": [
        -                                      {
        -                                        "enum": [
        -                                          "low",
        -                                          "high",
        -                                          "auto"
        -                                        ],
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  },
        -                                  "file_id": {
        -                                    "anyOf": [
        -                                      {
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  },
        -                                  "type": {
        -                                    "const": "input_image",
        -                                    "type": "string"
        -                                  },
        -                                  "url": {
        -                                    "anyOf": [
        -                                      {
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type"
        -                                ],
        -                                "type": "object"
        -                              },
        -                              {
        -                                "properties": {
        -                                  "file_id": {
        -                                    "type": "string"
        -                                  },
        -                                  "type": {
        -                                    "const": "input_file",
        -                                    "type": "string"
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type",
        -                                  "file_id"
        -                                ],
        -                                "type": "object"
        -                              }
        -                            ]
        -                          },
        -                          "type": "array"
        -                        }
        -                      ]
        -                    },
        -                    "role": {
        -                      "enum": [
        -                        "system",
        -                        "user",
        -                        "assistant"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    "type": {
        -                      "anyOf": [
        -                        {
        -                          "const": "message",
        -                          "type": "string"
        -                        },
        -                        {
        -                          "type": "null"
        -                        }
        -                      ]
        -                    }
        -                  },
        -                  "required": [
        -                    "role",
        -                    "content"
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              }
        -            ],
        -            "description": "Initial agent instructions — either a single system prompt string or a list of structured messages"
        -          },
        -          "models": {
        -            "description": "Model configuration for each capability the agent uses",
        -            "properties": {
        -              "agent": {
        -                "description": "Primary agent model configuration",
        -                "properties": {
        -                  "model": {
        -                    "description": "Model identifier used for the primary agent loop (Claude, or an OSS model when the team's oss_models flag — or oss_models_public for the public subset — is enabled)",
        -                    "enum": [
        -                      "claude-haiku-4-5-20251001",
        -                      "claude-haiku-5-5",
        -                      "claude-haiku-5-5[1m]",
        -                      "claude-sonnet-5",
        -                      "claude-sonnet-5[1m]",
        -                      "claude-sonnet-5-5",
        -                      "claude-sonnet-5-5[1m]",
        -                      "claude-opus-5",
        -                      "claude-opus-5[1m]",
        -                      "claude-opus-5-5",
        -                      "claude-opus-5-5[1m]",
        -                      "kimi-k3",
        -                      "kimi-k3-duvo",
        -                      "glm-5.3-flash",
        -                      "deepseek-v4-flash",
        -                      "deepseek-v4.1-flash",
        -                      "minimax-m3",
        -                      "d1-max",
        -                      "duvo-1-max",
        -                      "duvo-1-max-sonnet-1m",
        -                      "duvo-1-max-sonnet-4.5",
        -                      "duvo-1-max-sonnet-4.5-1m",
        -                      "duvo-1-max-opus",
        -                      "duvo-1-max-opus-4.5",
        -                      "gpt-4.1",
        -                      "gpt-4o",
        -                      "gpt-4o-mini",
        -                      "gpt-5",
        -                      "gpt-5.1",
        -                      "claude-sonnet-4-20250514",
        -                      "claude-sonnet-4-20250514[1m]",
        -                      "claude-sonnet-4-5-20250929",
        -                      "claude-sonnet-4-5-20250929[1m]",
        -                      "claude-sonnet-4-6",
        -                      "claude-sonnet-4-6[1m]",
        -                      "claude-opus-4-1-20250805",
        -                      "claude-opus-4-5-20251101",
        -                      "claude-opus-4-6",
        -                      "claude-opus-4-6[1m]",
        -                      "claude-opus-4-7",
        -                      "claude-opus-4-7[1m]",
        -                      "claude-opus-4-8",
        -                      "claude-opus-4-8[1m]",
        -                      "glm-5.2",
        -                      "qwen3.6-27b",
        -                      "qwen3.8-max"
        -                    ],
        -                    "type": "string",
        -                    "x-extensible-enum": [
        -                      "claude-haiku-4-5-20251001",
        -                      "claude-haiku-5-5",
        -                      "claude-haiku-5-5[1m]",
        -                      "claude-sonnet-5",
        -                      "claude-sonnet-5[1m]",
        -                      "claude-sonnet-5-5",
        -                      "claude-sonnet-5-5[1m]",
        -                      "claude-opus-5",
        -                      "claude-opus-5[1m]",
        -                      "claude-opus-5-5",
        -                      "claude-opus-5-5[1m]",
        -                      "kimi-k3",
        -                      "kimi-k3-duvo",
        -                      "glm-5.3-flash",
        -                      "deepseek-v4-flash",
        -                      "deepseek-v4.1-flash",
        -                      "minimax-m3",
        -                      "d1-max",
        -                      "duvo-1-max",
        -                      "duvo-1-max-sonnet-1m",
        -                      "duvo-1-max-sonnet-4.5",
        -                      "duvo-1-max-sonnet-4.5-1m",
        -                      "duvo-1-max-opus",
        -                      "duvo-1-max-opus-4.5",
        -                      "gpt-4.1",
        -                      "gpt-4o",
        -                      "gpt-4o-mini",
        -                      "gpt-5",
        -                      "gpt-5.1",
        -                      "claude-sonnet-4-20250514",
        -                      "claude-sonnet-4-20250514[1m]",
        -                      "claude-sonnet-4-5-20250929",
        -                      "claude-sonnet-4-5-20250929[1m]",
        -                      "claude-sonnet-4-6",
        -                      "claude-sonnet-4-6[1m]",
        -                      "claude-opus-4-1-20250805",
        -                      "claude-opus-4-5-20251101",
        -                      "claude-opus-4-6",
        -                      "claude-opus-4-6[1m]",
        -                      "claude-opus-4-7",
        -                      "claude-opus-4-7[1m]",
        -                      "claude-opus-4-8",
        -                      "claude-opus-4-8[1m]",
        -                      "glm-5.2",
        -                      "qwen3.6-27b",
        -                      "qwen3.8-max"
        -                    ]
        -                  }
        -                },
        -                "required": [
        -                  "model"
        -                ],
        -                "type": "object"
        -              },
        -              "browsing": {
        -                "description": "Browsing/computer-use model configuration",
        -                "properties": {
        -                  "model": {
        -                    "description": "Model identifier for the browsing provider",
        -                    "enum": [
        -                      "gemini-2.5-pro",
        -                      "gemini-2.5-flash",
        -                      "gemini-3-pro-preview",
        -                      "claude-haiku-4-5",
        -                      "claude-sonnet-4-5",
        -                      "claude-opus-4-1"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "provider": {
        -                    "description": "Provider backing the browsing/computer-use model",
        -                    "enum": [
        -                      "google",
        -                      "anthropic"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "provider",
        -                  "model"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "agent",
        -              "browsing"
        -            ],
        -            "type": "object"
        -          },
        -          "options": {
        -            "additionalProperties": {},
        -            "description": "Optional runtime options controlling how the agent executes",
        -            "properties": {
        -              "benchmarkExpectedOutcomes": {
        -                "description": "Expected outcomes used when running benchmark scenarios",
        -                "items": {
        -                  "properties": {
        -                    "criteria": {
        -                      "description": "Pass/fail criteria used to evaluate the outcome",
        -                      "type": "string"
        -                    },
        -                    "description": {
        -                      "description": "Human-readable description of the expected outcome",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "description",
        -                    "criteria"
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "browserProvider": {
        -                "description": "Browser infrastructure provider",
        -                "enum": [
        -                  "browserbase",
        -                  "browser-use"
        -                ],
        -                "type": "string"
        -              },
        -              "evaluationSchemaId": {
        -                "description": "ID of the evaluation schema to apply to runs of this agent",
        -                "type": "string"
        -              },
        -              "supervisedMode": {
        -                "description": "Run the agent under Duvo's permission classifier: every tool call is classified as allow/deny/ask, with 'ask' routed to human-in-the-loop approval. Mutually exclusive with browsing and computer-use connections.",
        -                "type": "boolean"
        -              }
        -            },
        -            "type": "object"
        -          },
        -          "plugins": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Plugins to load — either a built-in plugin name (e.g. \"code-review\") or a GitHub URL (e.g. \"https://github.com/owner/repo\")"
        -          },
        -          "skills": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "IDs of skills (team or system) that should be available to the agent"
        -          },
        -          "subAgents": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Retired — Sub-Assignments was removed. Accepted for backwards compatibility and ignored."
        -          }
        -        },
        -        "required": [
        -          "models",
        -          "input"
        -        ],
        -        "type": "object"
        -      },
        -      "version": {
        -        "const": "v2",
        -        "description": "Schema version discriminator — must be \"v2\" for the current schema",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "version",
        -      "data"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "properties": {
        -      "data": {
        -        "description": "Code step configuration payload",
        -        "properties": {
        -          "files": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Team file paths this step can read at run time"
        -          },
        -          "handoverRequired": {
        -            "default": false,
        -            "description": "When the step declares handover options, whether a run that exits cleanly without requesting one fails. Ignored when the step declares no options.",
        -            "type": "boolean"
        -          },
        -          "language": {
        -            "description": "Language the step's program is written in",
        -            "enum": [
        -              "python"
        -            ],
        -            "type": "string"
        -          },
        -          "maxConcurrency": {
        -            "description": "Most runs of this step that may be in flight at once on one queue, on top of the queue's own concurrency. Absent means only the queue's limit applies. Every claim enforces it; only cases handed to the step (handover, postpone, reprocess) are also kept out of the queue's free slots while the step is full. Cases a trigger or a revision route sends straight to a capped step can still take queue slots and wait there, delaying other steps on the same queue.",
        -            "exclusiveMinimum": 0,
        -            "maximum": 1000,
        -            "type": "integer"
        -          },
        -          "source": {
        -            "description": "Where the step's program comes from",
        -            "oneOf": [
        -              {
        -                "properties": {
        -                  "code": {
        -                    "description": "Program held in the build config. Written to `main.py` and run with `python main.py`.",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "kind": {
        -                    "const": "inline",
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "kind",
        -                  "code"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "properties": {
        -                  "bundle": {
        -                    "description": "The program's files, as a content-addressed manifest",
        -                    "properties": {
        -                      "bucket": {
        -                        "description": "GCS bucket the bundle's blobs are stored in",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "files": {
        -                        "description": "The program's files, one manifest entry each",
        -                        "items": {
        -                          "properties": {
        -                            "path": {
        -                              "description": "Path the file is materialised at, relative to the work dir",
        -                              "minLength": 1,
        -                              "type": "string"
        -                            },
        -                            "sha256": {
        -                              "description": "Digest of the file's bytes, and the key its blob is stored at",
        -                              "maxLength": 64,
        -                              "minLength": 64,
        -                              "pattern": "^[0-9a-f]{64}$",
        -                              "type": "string"
        -                            },
        -                            "sizeBytes": {
        -                              "description": "UTF-8 byte length of the file's contents",
        -                              "maximum": 131072,
        -                              "minimum": 0,
        -                              "type": "integer"
        -                            }
        -                          },
        -                          "required": [
        -                            "path",
        -                            "sha256",
        -                            "sizeBytes"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "maxItems": 200,
        -                        "type": "array"
        -                      }
        -                    },
        -                    "required": [
        -                      "bucket",
        -                      "files"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "kind": {
        -                    "const": "files",
        -                    "type": "string"
        -                  },
        -                  "startCommand": {
        -                    "description": "Command run from the root of the step's file system, e.g. \"python main.py\".",
        -                    "maxLength": 2000,
        -                    "minLength": 1,
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "kind",
        -                  "startCommand"
        -                ],
        -                "type": "object"
        -              }
        -            ]
        -          },
        -          "timeoutMs": {
        -            "default": 600000,
        -            "description": "Wall-clock budget for one execution of the step",
        -            "exclusiveMinimum": 0,
        -            "maximum": 3600000,
        -            "type": "integer"
        -          }
        -        },
        -        "required": [
        -          "language",
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "version": {
        -        "const": "v1",
        -        "description": "Schema version discriminator — must be \"v1\" for the current code-step schema",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "version",
        -      "data"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "properties": {
        +      "data": {
        +        "description": "Agent configuration payload",
        +        "properties": {
        +          "files": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Team files that should be available to the agent, each given as the relative file path returned in the `path` field of `GET /v2/teams/{teamId}/files` (for example `report.md` or `folder/doc.md`) — not the `id` field, which is a GCS object identifier."
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "items": {
        +                  "properties": {
        +                    "content": {
        +                      "anyOf": [
        +                        {
        +                          "type": "string"
        +                        },
        +                        {
        +                          "items": {
        +                            "anyOf": [
        +                              {
        +                                "properties": {
        +                                  "text": {
        +                                    "type": "string"
        +                                  },
        +                                  "type": {
        +                                    "const": "input_text",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "text"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              {
        +                                "properties": {
        +                                  "detail": {
        +                                    "anyOf": [
        +                                      {
        +                                        "enum": [
        +                                          "low",
        +                                          "high",
        +                                          "auto"
        +                                        ],
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  },
        +                                  "file_id": {
        +                                    "anyOf": [
        +                                      {
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  },
        +                                  "type": {
        +                                    "const": "input_image",
        +                                    "type": "string"
        +                                  },
        +                                  "url": {
        +                                    "anyOf": [
        +                                      {
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              {
        +                                "properties": {
        +                                  "file_id": {
        +                                    "type": "string"
        +                                  },
        +                                  "type": {
        +                                    "const": "input_file",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "file_id"
        +                                ],
        +                                "type": "object"
        +                              }
        +                            ]
        +                          },
        +                          "type": "array"
        +                        }
        +                      ]
        +                    },
        +                    "role": {
        +                      "enum": [
        +                        "system",
        +                        "user",
        +                        "assistant"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "type": {
        +                      "anyOf": [
        +                        {
        +                          "const": "message",
        +                          "type": "string"
        +                        },
        +                        {
        +                          "type": "null"
        +                        }
        +                      ]
        +                    }
        +                  },
        +                  "required": [
        +                    "role",
        +                    "content"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              }
        +            ],
        +            "description": "Initial agent instructions — either a single system prompt string or a list of structured messages"
        +          },
        +          "models": {
        +            "description": "Model configuration for each capability the agent uses",
        +            "properties": {
        +              "agent": {
        +                "description": "Primary agent model configuration",
        +                "properties": {
        +                  "model": {
        +                    "description": "Model identifier used for the primary agent loop (Claude, or an OSS model when the team's oss_models flag — or oss_models_public for the public subset — is enabled)",
        +                    "enum": [
        +                      "claude-haiku-4-5-20251001",
        +                      "claude-haiku-5-5",
        +                      "claude-haiku-5-5[1m]",
        +                      "claude-sonnet-5",
        +                      "claude-sonnet-5[1m]",
        +                      "claude-sonnet-5-5",
        +                      "claude-sonnet-5-5[1m]",
        +                      "claude-opus-5",
        +                      "claude-opus-5[1m]",
        +                      "claude-opus-5-5",
        +                      "claude-opus-5-5[1m]",
        +                      "kimi-k3",
        +                      "kimi-k3-duvo",
        +                      "glm-5.3-flash",
        +                      "deepseek-v4.1-flash",
        +                      "minimax-m3",
        +                      "d1-max",
        +                      "duvo-1-max",
        +                      "duvo-1-max-sonnet-1m",
        +                      "duvo-1-max-sonnet-4.5",
        +                      "duvo-1-max-sonnet-4.5-1m",
        +                      "duvo-1-max-opus",
        +                      "duvo-1-max-opus-4.5",
        +                      "gpt-4.1",
        +                      "gpt-4o",
        +                      "gpt-4o-mini",
        +                      "gpt-5",
        +                      "gpt-5.1",
        +                      "claude-sonnet-4-20250514",
        +                      "claude-sonnet-4-20250514[1m]",
        +                      "claude-sonnet-4-5-20250929",
        +                      "claude-sonnet-4-5-20250929[1m]",
        +                      "claude-sonnet-4-6",
        +                      "claude-sonnet-4-6[1m]",
        +                      "claude-opus-4-1-20250805",
        +                      "claude-opus-4-5-20251101",
        +                      "claude-opus-4-6",
        +                      "claude-opus-4-6[1m]",
        +                      "claude-opus-4-7",
        +                      "claude-opus-4-7[1m]",
        +                      "claude-opus-4-8",
        +                      "claude-opus-4-8[1m]",
        +                      "glm-5.2",
        +                      "qwen3.6-27b",
        +                      "qwen3.8-max",
        +                      "deepseek-v4-flash"
        +                    ],
        +                    "type": "string",
        +                    "x-extensible-enum": [
        +                      "claude-haiku-4-5-20251001",
        +                      "claude-haiku-5-5",
        +                      "claude-haiku-5-5[1m]",
        +                      "claude-sonnet-5",
        +                      "claude-sonnet-5[1m]",
        +                      "claude-sonnet-5-5",
        +                      "claude-sonnet-5-5[1m]",
        +                      "claude-opus-5",
        +                      "claude-opus-5[1m]",
        +                      "claude-opus-5-5",
        +                      "claude-opus-5-5[1m]",
        +                      "kimi-k3",
        +                      "kimi-k3-duvo",
        +                      "glm-5.3-flash",
        +                      "deepseek-v4.1-flash",
        +                      "minimax-m3",
        +                      "d1-max",
        +                      "duvo-1-max",
        +                      "duvo-1-max-sonnet-1m",
        +                      "duvo-1-max-sonnet-4.5",
        +                      "duvo-1-max-sonnet-4.5-1m",
        +                      "duvo-1-max-opus",
        +                      "duvo-1-max-opus-4.5",
        +                      "gpt-4.1",
        +                      "gpt-4o",
        +                      "gpt-4o-mini",
        +                      "gpt-5",
        +                      "gpt-5.1",
        +                      "claude-sonnet-4-20250514",
        +                      "claude-sonnet-4-20250514[1m]",
        +                      "claude-sonnet-4-5-20250929",
        +                      "claude-sonnet-4-5-20250929[1m]",
        +                      "claude-sonnet-4-6",
        +                      "claude-sonnet-4-6[1m]",
        +                      "claude-opus-4-1-20250805",
        +                      "claude-opus-4-5-20251101",
        +                      "claude-opus-4-6",
        +                      "claude-opus-4-6[1m]",
        +                      "claude-opus-4-7",
        +                      "claude-opus-4-7[1m]",
        +                      "claude-opus-4-8",
        +                      "claude-opus-4-8[1m]",
        +                      "glm-5.2",
        +                      "qwen3.6-27b",
        +                      "qwen3.8-max",
        +                      "deepseek-v4-flash"
        +                    ]
        +                  }
        +                },
        +                "required": [
        +                  "model"
        +                ],
        +                "type": "object"
        +              },
        +              "browsing": {
        +                "description": "Browsing/computer-use model configuration",
        +                "properties": {
        +                  "model": {
        +                    "description": "Model identifier for the browsing provider",
        +                    "enum": [
        +                      "gemini-2.5-pro",
        +                      "gemini-2.5-flash",
        +                      "gemini-3-pro-preview",
        +                      "claude-haiku-4-5",
        +                      "claude-sonnet-4-5",
        +                      "claude-opus-4-1"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "provider": {
        +                    "description": "Provider backing the browsing/computer-use model",
        +                    "enum": [
        +                      "google",
        +                      "anthropic"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "provider",
        +                  "model"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "agent",
        +              "browsing"
        +            ],
        +            "type": "object"
        +          },
        +          "options": {
        +            "additionalProperties": {},
        +            "description": "Optional runtime options controlling how the agent executes",
        +            "properties": {
        +              "benchmarkExpectedOutcomes": {
        +                "description": "Expected outcomes used when running benchmark scenarios",
        +                "items": {
        +                  "properties": {
        +                    "criteria": {
        +                      "description": "Pass/fail criteria used to evaluate the outcome",
        +                      "type": "string"
        +                    },
        +                    "description": {
        +                      "description": "Human-readable description of the expected outcome",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "description",
        +                    "criteria"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "browserProvider": {
        +                "description": "Browser infrastructure provider",
        +                "enum": [
        +                  "browserbase",
        +                  "browser-use"
        +                ],
        +                "type": "string"
        +              },
        +              "evaluationSchemaId": {
        +                "description": "ID of the evaluation schema to apply to runs of this agent",
        +                "type": "string"
        +              },
        +              "supervisedMode": {
        +                "description": "Run the agent under Duvo's permission classifier: every tool call is classified as allow/deny/ask, with 'ask' routed to human-in-the-loop approval. Mutually exclusive with browsing and computer-use connections.",
        +                "type": "boolean"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "plugins": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Plugins to load — either a built-in plugin name (e.g. \"code-review\") or a GitHub URL (e.g. \"https://github.com/owner/repo\")"
        +          },
        +          "skills": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "IDs of skills (team or system) that should be available to the agent"
        +          },
        +          "subAgents": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Retired — Sub-Assignments was removed. Accepted for backwards compatibility and ignored."
        +          }
        +        },
        +        "required": [
        +          "models",
        +          "input"
        +        ],
        +        "type": "object"
        +      },
        +      "version": {
        +        "const": "v2",
        +        "description": "Schema version discriminator — must be \"v2\" for the current schema",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "version",
        +      "data"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "data": {
        +        "description": "Code step configuration payload",
        +        "properties": {
        +          "files": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Team file paths this step can read at run time"
        +          },
        +          "handoverRequired": {
        +            "default": false,
        +            "description": "When the step declares handover options, whether a run that exits cleanly without requesting one fails. Ignored when the step declares no options.",
        +            "type": "boolean"
        +          },
        +          "language": {
        +            "description": "Language the step's program is written in",
        +            "enum": [
        +              "python"
        +            ],
        +            "type": "string"
        +          },
        +          "maxConcurrency": {
        +            "description": "Most runs of this step that may be in flight at once on one queue, on top of the queue's own concurrency. Absent means only the queue's limit applies. Every claim enforces it; only cases handed to the step (handover, postpone, reprocess) are also kept out of the queue's free slots while the step is full. Cases a trigger or a revision route sends straight to a capped step can still take queue slots and wait there, delaying other steps on the same queue.",
        +            "exclusiveMinimum": 0,
        +            "maximum": 1000,
        +            "type": "integer"
        +          },
        +          "source": {
        +            "description": "Where the step's program comes from",
        +            "oneOf": [
        +              {
        +                "properties": {
        +                  "code": {
        +                    "description": "Program held in the build config. Written to `main.py` and run with `python main.py`.",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "kind": {
        +                    "const": "inline",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "kind",
        +                  "code"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "properties": {
        +                  "bundle": {
        +                    "description": "The program's files, as a content-addressed manifest",
        +                    "properties": {
        +                      "bucket": {
        +                        "description": "GCS bucket the bundle's blobs are stored in",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "files": {
        +                        "description": "The program's files, one manifest entry each",
        +                        "items": {
        +                          "properties": {
        +                            "path": {
        +                              "description": "Path the file is materialised at, relative to the work dir",
        +                              "minLength": 1,
        +                              "type": "string"
        +                            },
        +                            "sha256": {
        +                              "description": "Digest of the file's bytes, and the key its blob is stored at",
        +                              "maxLength": 64,
        +                              "minLength": 64,
        +                              "pattern": "^[0-9a-f]{64}$",
        +                              "type": "string"
        +                            },
        +                            "sizeBytes": {
        +                              "description": "UTF-8 byte length of the file's contents",
        +                              "maximum": 131072,
        +                              "minimum": 0,
        +                              "type": "integer"
        +                            }
        +                          },
        +                          "required": [
        +                            "path",
        +                            "sha256",
        +                            "sizeBytes"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "maxItems": 200,
        +                        "type": "array"
        +                      }
        +                    },
        +                    "required": [
        +                      "bucket",
        +                      "files"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "kind": {
        +                    "const": "files",
        +                    "type": "string"
        +                  },
        +                  "startCommand": {
        +                    "description": "Command run from the root of the step's file system, e.g. \"python main.py\".",
        +                    "maxLength": 2000,
        +                    "minLength": 1,
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "kind",
        +                  "startCommand"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "timeoutMs": {
        +            "default": 600000,
        +            "description": "Wall-clock budget for one execution of the step",
        +            "exclusiveMinimum": 0,
        +            "maximum": 3600000,
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "language",
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "version": {
        +        "const": "v1",
        +        "description": "Schema version discriminator — must be \"v1\" for the current code-step schema",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "version",
        +      "data"
        +    ],
        +    "type": "object"
        +  }
        +]
  15. 4 tool updates
    • ChangedcreateAgent2 fields changed
      • changedInput schema / properties / build / properties / config / properties / data / properties / models / properties / agent / properties / model / enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4-flash",
        +  "deepseek-v4.1-flash",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max"
        +]
      • changedInput schema / properties / build / properties / config / properties / data / properties / models / properties / agent / properties / model / x-extensible-enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4-flash",
        +  "deepseek-v4.1-flash",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max"
        +]
    • ChangedcreateAutomation2 fields changed
      • changedInput schema / properties / first_agent / properties / config / properties / data / properties / models / properties / agent / properties / model / enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4-flash",
        +  "deepseek-v4.1-flash",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max"
        +]
      • changedInput schema / properties / first_agent / properties / config / properties / data / properties / models / properties / agent / properties / model / x-extensible-enum
        Previous value: -[
        -  "claude-haiku-4-5-20251001",
        -  "claude-haiku-5-5",
        -  "claude-haiku-5-5[1m]",
        -  "claude-sonnet-5",
        -  "claude-sonnet-5[1m]",
        -  "claude-sonnet-5-5",
        -  "claude-sonnet-5-5[1m]",
        -  "claude-opus-5",
        -  "claude-opus-5[1m]",
        -  "claude-opus-5-5",
        -  "claude-opus-5-5[1m]",
        -  "kimi-k3",
        -  "kimi-k3-duvo",
        -  "glm-5.3-flash",
        -  "deepseek-v4-flash",
        -  "minimax-m3",
        -  "d1-max",
        -  "duvo-1-max",
        -  "duvo-1-max-sonnet-1m",
        -  "duvo-1-max-sonnet-4.5",
        -  "duvo-1-max-sonnet-4.5-1m",
        -  "duvo-1-max-opus",
        -  "duvo-1-max-opus-4.5",
        -  "gpt-4.1",
        -  "gpt-4o",
        -  "gpt-4o-mini",
        -  "gpt-5",
        -  "gpt-5.1",
        -  "claude-sonnet-4-20250514",
        -  "claude-sonnet-4-20250514[1m]",
        -  "claude-sonnet-4-5-20250929",
        -  "claude-sonnet-4-5-20250929[1m]",
        -  "claude-sonnet-4-6",
        -  "claude-sonnet-4-6[1m]",
        -  "claude-opus-4-1-20250805",
        -  "claude-opus-4-5-20251101",
        -  "claude-opus-4-6",
        -  "claude-opus-4-6[1m]",
        -  "claude-opus-4-7",
        -  "claude-opus-4-7[1m]",
        -  "claude-opus-4-8",
        -  "claude-opus-4-8[1m]",
        -  "glm-5.2",
        -  "qwen3.6-27b",
        -  "qwen3.8-max"
        -]New value: +[
        +  "claude-haiku-4-5-20251001",
        +  "claude-haiku-5-5",
        +  "claude-haiku-5-5[1m]",
        +  "claude-sonnet-5",
        +  "claude-sonnet-5[1m]",
        +  "claude-sonnet-5-5",
        +  "claude-sonnet-5-5[1m]",
        +  "claude-opus-5",
        +  "claude-opus-5[1m]",
        +  "claude-opus-5-5",
        +  "claude-opus-5-5[1m]",
        +  "kimi-k3",
        +  "kimi-k3-duvo",
        +  "glm-5.3-flash",
        +  "deepseek-v4-flash",
        +  "deepseek-v4.1-flash",
        +  "minimax-m3",
        +  "d1-max",
        +  "duvo-1-max",
        +  "duvo-1-max-sonnet-1m",
        +  "duvo-1-max-sonnet-4.5",
        +  "duvo-1-max-sonnet-4.5-1m",
        +  "duvo-1-max-opus",
        +  "duvo-1-max-opus-4.5",
        +  "gpt-4.1",
        +  "gpt-4o",
        +  "gpt-4o-mini",
        +  "gpt-5",
        +  "gpt-5.1",
        +  "claude-sonnet-4-20250514",
        +  "claude-sonnet-4-20250514[1m]",
        +  "claude-sonnet-4-5-20250929",
        +  "claude-sonnet-4-5-20250929[1m]",
        +  "claude-sonnet-4-6",
        +  "claude-sonnet-4-6[1m]",
        +  "claude-opus-4-1-20250805",
        +  "claude-opus-4-5-20251101",
        +  "claude-opus-4-6",
        +  "claude-opus-4-6[1m]",
        +  "claude-opus-4-7",
        +  "claude-opus-4-7[1m]",
        +  "claude-opus-4-8",
        +  "claude-opus-4-8[1m]",
        +  "glm-5.2",
        +  "qwen3.6-27b",
        +  "qwen3.8-max"
        +]
    • ChangedcreateRevision1 field changed
      • changedInput schema / properties / config / anyOf
        Previous value: -[
        -  {
        -    "properties": {
        -      "data": {
        -        "description": "Agent configuration payload",
        -        "properties": {
        -          "files": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Team files that should be available to the agent, each given as the relative file path returned in the `path` field of `GET /v2/teams/{teamId}/files` (for example `report.md` or `folder/doc.md`) — not the `id` field, which is a GCS object identifier."
        -          },
        -          "input": {
        -            "anyOf": [
        -              {
        -                "type": "string"
        -              },
        -              {
        -                "items": {
        -                  "properties": {
        -                    "content": {
        -                      "anyOf": [
        -                        {
        -                          "type": "string"
        -                        },
        -                        {
        -                          "items": {
        -                            "anyOf": [
        -                              {
        -                                "properties": {
        -                                  "text": {
        -                                    "type": "string"
        -                                  },
        -                                  "type": {
        -                                    "const": "input_text",
        -                                    "type": "string"
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type",
        -                                  "text"
        -                                ],
        -                                "type": "object"
        -                              },
        -                              {
        -                                "properties": {
        -                                  "detail": {
        -                                    "anyOf": [
        -                                      {
        -                                        "enum": [
        -                                          "low",
        -                                          "high",
        -                                          "auto"
        -                                        ],
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  },
        -                                  "file_id": {
        -                                    "anyOf": [
        -                                      {
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  },
        -                                  "type": {
        -                                    "const": "input_image",
        -                                    "type": "string"
        -                                  },
        -                                  "url": {
        -                                    "anyOf": [
        -                                      {
        -                                        "type": "string"
        -                                      },
        -                                      {
        -                                        "type": "null"
        -                                      }
        -                                    ]
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type"
        -                                ],
        -                                "type": "object"
        -                              },
        -                              {
        -                                "properties": {
        -                                  "file_id": {
        -                                    "type": "string"
        -                                  },
        -                                  "type": {
        -                                    "const": "input_file",
        -                                    "type": "string"
        -                                  }
        -                                },
        -                                "required": [
        -                                  "type",
        -                                  "file_id"
        -                                ],
        -                                "type": "object"
        -                              }
        -                            ]
        -                          },
        -                          "type": "array"
        -                        }
        -                      ]
        -                    },
        -                    "role": {
        -                      "enum": [
        -                        "system",
        -                        "user",
        -                        "assistant"
        -                      ],
        -                      "type": "string"
        -                    },
        -                    "type": {
        -                      "anyOf": [
        -                        {
        -                          "const": "message",
        -                          "type": "string"
        -                        },
        -                        {
        -                          "type": "null"
        -                        }
        -                      ]
        -                    }
        -                  },
        -                  "required": [
        -                    "role",
        -                    "content"
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              }
        -            ],
        -            "description": "Initial agent instructions — either a single system prompt string or a list of structured messages"
        -          },
        -          "models": {
        -            "description": "Model configuration for each capability the agent uses",
        -            "properties": {
        -              "agent": {
        -                "description": "Primary agent model configuration",
        -                "properties": {
        -                  "model": {
        -                    "description": "Model identifier used for the primary agent loop (Claude, or an OSS model when the team's oss_models flag — or oss_models_public for the public subset — is enabled)",
        -                    "enum": [
        -                      "claude-haiku-4-5-20251001",
        -                      "claude-haiku-5-5",
        -                      "claude-haiku-5-5[1m]",
        -                      "claude-sonnet-5",
        -                      "claude-sonnet-5[1m]",
        -                      "claude-sonnet-5-5",
        -                      "claude-sonnet-5-5[1m]",
        -                      "claude-opus-5",
        -                      "claude-opus-5[1m]",
        -                      "claude-opus-5-5",
        -                      "claude-opus-5-5[1m]",
        -                      "kimi-k3",
        -                      "kimi-k3-duvo",
        -                      "glm-5.3-flash",
        -                      "deepseek-v4-flash",
        -                      "minimax-m3",
        -                      "d1-max",
        -                      "duvo-1-max",
        -                      "duvo-1-max-sonnet-1m",
        -                      "duvo-1-max-sonnet-4.5",
        -                      "duvo-1-max-sonnet-4.5-1m",
        -                      "duvo-1-max-opus",
        -                      "duvo-1-max-opus-4.5",
        -                      "gpt-4.1",
        -                      "gpt-4o",
        -                      "gpt-4o-mini",
        -                      "gpt-5",
        -                      "gpt-5.1",
        -                      "claude-sonnet-4-20250514",
        -                      "claude-sonnet-4-20250514[1m]",
        -                      "claude-sonnet-4-5-20250929",
        -                      "claude-sonnet-4-5-20250929[1m]",
        -                      "claude-sonnet-4-6",
        -                      "claude-sonnet-4-6[1m]",
        -                      "claude-opus-4-1-20250805",
        -                      "claude-opus-4-5-20251101",
        -                      "claude-opus-4-6",
        -                      "claude-opus-4-6[1m]",
        -                      "claude-opus-4-7",
        -                      "claude-opus-4-7[1m]",
        -                      "claude-opus-4-8",
        -                      "claude-opus-4-8[1m]",
        -                      "glm-5.2",
        -                      "qwen3.6-27b",
        -                      "qwen3.8-max"
        -                    ],
        -                    "type": "string",
        -                    "x-extensible-enum": [
        -                      "claude-haiku-4-5-20251001",
        -                      "claude-haiku-5-5",
        -                      "claude-haiku-5-5[1m]",
        -                      "claude-sonnet-5",
        -                      "claude-sonnet-5[1m]",
        -                      "claude-sonnet-5-5",
        -                      "claude-sonnet-5-5[1m]",
        -                      "claude-opus-5",
        -                      "claude-opus-5[1m]",
        -                      "claude-opus-5-5",
        -                      "claude-opus-5-5[1m]",
        -                      "kimi-k3",
        -                      "kimi-k3-duvo",
        -                      "glm-5.3-flash",
        -                      "deepseek-v4-flash",
        -                      "minimax-m3",
        -                      "d1-max",
        -                      "duvo-1-max",
        -                      "duvo-1-max-sonnet-1m",
        -                      "duvo-1-max-sonnet-4.5",
        -                      "duvo-1-max-sonnet-4.5-1m",
        -                      "duvo-1-max-opus",
        -                      "duvo-1-max-opus-4.5",
        -                      "gpt-4.1",
        -                      "gpt-4o",
        -                      "gpt-4o-mini",
        -                      "gpt-5",
        -                      "gpt-5.1",
        -                      "claude-sonnet-4-20250514",
        -                      "claude-sonnet-4-20250514[1m]",
        -                      "claude-sonnet-4-5-20250929",
        -                      "claude-sonnet-4-5-20250929[1m]",
        -                      "claude-sonnet-4-6",
        -                      "claude-sonnet-4-6[1m]",
        -                      "claude-opus-4-1-20250805",
        -                      "claude-opus-4-5-20251101",
        -                      "claude-opus-4-6",
        -                      "claude-opus-4-6[1m]",
        -                      "claude-opus-4-7",
        -                      "claude-opus-4-7[1m]",
        -                      "claude-opus-4-8",
        -                      "claude-opus-4-8[1m]",
        -                      "glm-5.2",
        -                      "qwen3.6-27b",
        -                      "qwen3.8-max"
        -                    ]
        -                  }
        -                },
        -                "required": [
        -                  "model"
        -                ],
        -                "type": "object"
        -              },
        -              "browsing": {
        -                "description": "Browsing/computer-use model configuration",
        -                "properties": {
        -                  "model": {
        -                    "description": "Model identifier for the browsing provider",
        -                    "enum": [
        -                      "gemini-2.5-pro",
        -                      "gemini-2.5-flash",
        -                      "gemini-3-pro-preview",
        -                      "claude-haiku-4-5",
        -                      "claude-sonnet-4-5",
        -                      "claude-opus-4-1"
        -                    ],
        -                    "type": "string"
        -                  },
        -                  "provider": {
        -                    "description": "Provider backing the browsing/computer-use model",
        -                    "enum": [
        -                      "google",
        -                      "anthropic"
        -                    ],
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "provider",
        -                  "model"
        -                ],
        -                "type": "object"
        -              }
        -            },
        -            "required": [
        -              "agent",
        -              "browsing"
        -            ],
        -            "type": "object"
        -          },
        -          "options": {
        -            "additionalProperties": {},
        -            "description": "Optional runtime options controlling how the agent executes",
        -            "properties": {
        -              "benchmarkExpectedOutcomes": {
        -                "description": "Expected outcomes used when running benchmark scenarios",
        -                "items": {
        -                  "properties": {
        -                    "criteria": {
        -                      "description": "Pass/fail criteria used to evaluate the outcome",
        -                      "type": "string"
        -                    },
        -                    "description": {
        -                      "description": "Human-readable description of the expected outcome",
        -                      "type": "string"
        -                    }
        -                  },
        -                  "required": [
        -                    "description",
        -                    "criteria"
        -                  ],
        -                  "type": "object"
        -                },
        -                "type": "array"
        -              },
        -              "browserProvider": {
        -                "description": "Browser infrastructure provider",
        -                "enum": [
        -                  "browserbase",
        -                  "browser-use"
        -                ],
        -                "type": "string"
        -              },
        -              "evaluationSchemaId": {
        -                "description": "ID of the evaluation schema to apply to runs of this agent",
        -                "type": "string"
        -              },
        -              "supervisedMode": {
        -                "description": "Run the agent under Duvo's permission classifier: every tool call is classified as allow/deny/ask, with 'ask' routed to human-in-the-loop approval. Mutually exclusive with browsing and computer-use connections.",
        -                "type": "boolean"
        -              }
        -            },
        -            "type": "object"
        -          },
        -          "plugins": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Plugins to load — either a built-in plugin name (e.g. \"code-review\") or a GitHub URL (e.g. \"https://github.com/owner/repo\")"
        -          },
        -          "skills": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "IDs of skills (team or system) that should be available to the agent"
        -          },
        -          "subAgents": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "format": "uuid",
        -                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Retired — Sub-Assignments was removed. Accepted for backwards compatibility and ignored."
        -          }
        -        },
        -        "required": [
        -          "models",
        -          "input"
        -        ],
        -        "type": "object"
        -      },
        -      "version": {
        -        "const": "v2",
        -        "description": "Schema version discriminator — must be \"v2\" for the current schema",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "version",
        -      "data"
        -    ],
        -    "type": "object"
        -  },
        -  {
        -    "properties": {
        -      "data": {
        -        "description": "Code step configuration payload",
        -        "properties": {
        -          "files": {
        -            "anyOf": [
        -              {
        -                "items": {
        -                  "type": "string"
        -                },
        -                "type": "array"
        -              },
        -              {
        -                "type": "null"
        -              }
        -            ],
        -            "default": [],
        -            "description": "Team file paths this step can read at run time"
        -          },
        -          "handoverRequired": {
        -            "default": false,
        -            "description": "When the step declares handover options, whether a run that exits cleanly without requesting one fails. Ignored when the step declares no options.",
        -            "type": "boolean"
        -          },
        -          "language": {
        -            "description": "Language the step's program is written in",
        -            "enum": [
        -              "python"
        -            ],
        -            "type": "string"
        -          },
        -          "maxConcurrency": {
        -            "description": "Most runs of this step that may be in flight at once on one queue, on top of the queue's own concurrency. Absent means only the queue's limit applies. Every claim enforces it; only cases handed to the step (handover, postpone, reprocess) are also kept out of the queue's free slots while the step is full. Cases a trigger or a revision route sends straight to a capped step can still take queue slots and wait there, delaying other steps on the same queue.",
        -            "exclusiveMinimum": 0,
        -            "maximum": 1000,
        -            "type": "integer"
        -          },
        -          "source": {
        -            "description": "Where the step's program comes from",
        -            "oneOf": [
        -              {
        -                "properties": {
        -                  "code": {
        -                    "description": "Program held in the build config. Written to `main.py` and run with `python main.py`.",
        -                    "minLength": 1,
        -                    "type": "string"
        -                  },
        -                  "kind": {
        -                    "const": "inline",
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "kind",
        -                  "code"
        -                ],
        -                "type": "object"
        -              },
        -              {
        -                "properties": {
        -                  "bundle": {
        -                    "description": "The program's files, as a content-addressed manifest",
        -                    "properties": {
        -                      "bucket": {
        -                        "description": "GCS bucket the bundle's blobs are stored in",
        -                        "minLength": 1,
        -                        "type": "string"
        -                      },
        -                      "files": {
        -                        "description": "The program's files, one manifest entry each",
        -                        "items": {
        -                          "properties": {
        -                            "path": {
        -                              "description": "Path the file is materialised at, relative to the work dir",
        -                              "minLength": 1,
        -                              "type": "string"
        -                            },
        -                            "sha256": {
        -                              "description": "Digest of the file's bytes, and the key its blob is stored at",
        -                              "maxLength": 64,
        -                              "minLength": 64,
        -                              "pattern": "^[0-9a-f]{64}$",
        -                              "type": "string"
        -                            },
        -                            "sizeBytes": {
        -                              "description": "UTF-8 byte length of the file's contents",
        -                              "maximum": 131072,
        -                              "minimum": 0,
        -                              "type": "integer"
        -                            }
        -                          },
        -                          "required": [
        -                            "path",
        -                            "sha256",
        -                            "sizeBytes"
        -                          ],
        -                          "type": "object"
        -                        },
        -                        "maxItems": 200,
        -                        "type": "array"
        -                      }
        -                    },
        -                    "required": [
        -                      "bucket",
        -                      "files"
        -                    ],
        -                    "type": "object"
        -                  },
        -                  "kind": {
        -                    "const": "files",
        -                    "type": "string"
        -                  },
        -                  "startCommand": {
        -                    "description": "Command run from the root of the step's file system, e.g. \"python main.py\".",
        -                    "maxLength": 2000,
        -                    "minLength": 1,
        -                    "type": "string"
        -                  }
        -                },
        -                "required": [
        -                  "kind",
        -                  "startCommand"
        -                ],
        -                "type": "object"
        -              }
        -            ]
        -          },
        -          "timeoutMs": {
        -            "default": 600000,
        -            "description": "Wall-clock budget for one execution of the step",
        -            "exclusiveMinimum": 0,
        -            "maximum": 3600000,
        -            "type": "integer"
        -          }
        -        },
        -        "required": [
        -          "language",
        -          "source"
        -        ],
        -        "type": "object"
        -      },
        -      "version": {
        -        "const": "v1",
        -        "description": "Schema version discriminator — must be \"v1\" for the current code-step schema",
        -        "type": "string"
        -      }
        -    },
        -    "required": [
        -      "version",
        -      "data"
        -    ],
        -    "type": "object"
        -  }
        -]New value: +[
        +  {
        +    "properties": {
        +      "data": {
        +        "description": "Agent configuration payload",
        +        "properties": {
        +          "files": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Team files that should be available to the agent, each given as the relative file path returned in the `path` field of `GET /v2/teams/{teamId}/files` (for example `report.md` or `folder/doc.md`) — not the `id` field, which is a GCS object identifier."
        +          },
        +          "input": {
        +            "anyOf": [
        +              {
        +                "type": "string"
        +              },
        +              {
        +                "items": {
        +                  "properties": {
        +                    "content": {
        +                      "anyOf": [
        +                        {
        +                          "type": "string"
        +                        },
        +                        {
        +                          "items": {
        +                            "anyOf": [
        +                              {
        +                                "properties": {
        +                                  "text": {
        +                                    "type": "string"
        +                                  },
        +                                  "type": {
        +                                    "const": "input_text",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "text"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              {
        +                                "properties": {
        +                                  "detail": {
        +                                    "anyOf": [
        +                                      {
        +                                        "enum": [
        +                                          "low",
        +                                          "high",
        +                                          "auto"
        +                                        ],
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  },
        +                                  "file_id": {
        +                                    "anyOf": [
        +                                      {
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  },
        +                                  "type": {
        +                                    "const": "input_image",
        +                                    "type": "string"
        +                                  },
        +                                  "url": {
        +                                    "anyOf": [
        +                                      {
        +                                        "type": "string"
        +                                      },
        +                                      {
        +                                        "type": "null"
        +                                      }
        +                                    ]
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type"
        +                                ],
        +                                "type": "object"
        +                              },
        +                              {
        +                                "properties": {
        +                                  "file_id": {
        +                                    "type": "string"
        +                                  },
        +                                  "type": {
        +                                    "const": "input_file",
        +                                    "type": "string"
        +                                  }
        +                                },
        +                                "required": [
        +                                  "type",
        +                                  "file_id"
        +                                ],
        +                                "type": "object"
        +                              }
        +                            ]
        +                          },
        +                          "type": "array"
        +                        }
        +                      ]
        +                    },
        +                    "role": {
        +                      "enum": [
        +                        "system",
        +                        "user",
        +                        "assistant"
        +                      ],
        +                      "type": "string"
        +                    },
        +                    "type": {
        +                      "anyOf": [
        +                        {
        +                          "const": "message",
        +                          "type": "string"
        +                        },
        +                        {
        +                          "type": "null"
        +                        }
        +                      ]
        +                    }
        +                  },
        +                  "required": [
        +                    "role",
        +                    "content"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              }
        +            ],
        +            "description": "Initial agent instructions — either a single system prompt string or a list of structured messages"
        +          },
        +          "models": {
        +            "description": "Model configuration for each capability the agent uses",
        +            "properties": {
        +              "agent": {
        +                "description": "Primary agent model configuration",
        +                "properties": {
        +                  "model": {
        +                    "description": "Model identifier used for the primary agent loop (Claude, or an OSS model when the team's oss_models flag — or oss_models_public for the public subset — is enabled)",
        +                    "enum": [
        +                      "claude-haiku-4-5-20251001",
        +                      "claude-haiku-5-5",
        +                      "claude-haiku-5-5[1m]",
        +                      "claude-sonnet-5",
        +                      "claude-sonnet-5[1m]",
        +                      "claude-sonnet-5-5",
        +                      "claude-sonnet-5-5[1m]",
        +                      "claude-opus-5",
        +                      "claude-opus-5[1m]",
        +                      "claude-opus-5-5",
        +                      "claude-opus-5-5[1m]",
        +                      "kimi-k3",
        +                      "kimi-k3-duvo",
        +                      "glm-5.3-flash",
        +                      "deepseek-v4-flash",
        +                      "deepseek-v4.1-flash",
        +                      "minimax-m3",
        +                      "d1-max",
        +                      "duvo-1-max",
        +                      "duvo-1-max-sonnet-1m",
        +                      "duvo-1-max-sonnet-4.5",
        +                      "duvo-1-max-sonnet-4.5-1m",
        +                      "duvo-1-max-opus",
        +                      "duvo-1-max-opus-4.5",
        +                      "gpt-4.1",
        +                      "gpt-4o",
        +                      "gpt-4o-mini",
        +                      "gpt-5",
        +                      "gpt-5.1",
        +                      "claude-sonnet-4-20250514",
        +                      "claude-sonnet-4-20250514[1m]",
        +                      "claude-sonnet-4-5-20250929",
        +                      "claude-sonnet-4-5-20250929[1m]",
        +                      "claude-sonnet-4-6",
        +                      "claude-sonnet-4-6[1m]",
        +                      "claude-opus-4-1-20250805",
        +                      "claude-opus-4-5-20251101",
        +                      "claude-opus-4-6",
        +                      "claude-opus-4-6[1m]",
        +                      "claude-opus-4-7",
        +                      "claude-opus-4-7[1m]",
        +                      "claude-opus-4-8",
        +                      "claude-opus-4-8[1m]",
        +                      "glm-5.2",
        +                      "qwen3.6-27b",
        +                      "qwen3.8-max"
        +                    ],
        +                    "type": "string",
        +                    "x-extensible-enum": [
        +                      "claude-haiku-4-5-20251001",
        +                      "claude-haiku-5-5",
        +                      "claude-haiku-5-5[1m]",
        +                      "claude-sonnet-5",
        +                      "claude-sonnet-5[1m]",
        +                      "claude-sonnet-5-5",
        +                      "claude-sonnet-5-5[1m]",
        +                      "claude-opus-5",
        +                      "claude-opus-5[1m]",
        +                      "claude-opus-5-5",
        +                      "claude-opus-5-5[1m]",
        +                      "kimi-k3",
        +                      "kimi-k3-duvo",
        +                      "glm-5.3-flash",
        +                      "deepseek-v4-flash",
        +                      "deepseek-v4.1-flash",
        +                      "minimax-m3",
        +                      "d1-max",
        +                      "duvo-1-max",
        +                      "duvo-1-max-sonnet-1m",
        +                      "duvo-1-max-sonnet-4.5",
        +                      "duvo-1-max-sonnet-4.5-1m",
        +                      "duvo-1-max-opus",
        +                      "duvo-1-max-opus-4.5",
        +                      "gpt-4.1",
        +                      "gpt-4o",
        +                      "gpt-4o-mini",
        +                      "gpt-5",
        +                      "gpt-5.1",
        +                      "claude-sonnet-4-20250514",
        +                      "claude-sonnet-4-20250514[1m]",
        +                      "claude-sonnet-4-5-20250929",
        +                      "claude-sonnet-4-5-20250929[1m]",
        +                      "claude-sonnet-4-6",
        +                      "claude-sonnet-4-6[1m]",
        +                      "claude-opus-4-1-20250805",
        +                      "claude-opus-4-5-20251101",
        +                      "claude-opus-4-6",
        +                      "claude-opus-4-6[1m]",
        +                      "claude-opus-4-7",
        +                      "claude-opus-4-7[1m]",
        +                      "claude-opus-4-8",
        +                      "claude-opus-4-8[1m]",
        +                      "glm-5.2",
        +                      "qwen3.6-27b",
        +                      "qwen3.8-max"
        +                    ]
        +                  }
        +                },
        +                "required": [
        +                  "model"
        +                ],
        +                "type": "object"
        +              },
        +              "browsing": {
        +                "description": "Browsing/computer-use model configuration",
        +                "properties": {
        +                  "model": {
        +                    "description": "Model identifier for the browsing provider",
        +                    "enum": [
        +                      "gemini-2.5-pro",
        +                      "gemini-2.5-flash",
        +                      "gemini-3-pro-preview",
        +                      "claude-haiku-4-5",
        +                      "claude-sonnet-4-5",
        +                      "claude-opus-4-1"
        +                    ],
        +                    "type": "string"
        +                  },
        +                  "provider": {
        +                    "description": "Provider backing the browsing/computer-use model",
        +                    "enum": [
        +                      "google",
        +                      "anthropic"
        +                    ],
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "provider",
        +                  "model"
        +                ],
        +                "type": "object"
        +              }
        +            },
        +            "required": [
        +              "agent",
        +              "browsing"
        +            ],
        +            "type": "object"
        +          },
        +          "options": {
        +            "additionalProperties": {},
        +            "description": "Optional runtime options controlling how the agent executes",
        +            "properties": {
        +              "benchmarkExpectedOutcomes": {
        +                "description": "Expected outcomes used when running benchmark scenarios",
        +                "items": {
        +                  "properties": {
        +                    "criteria": {
        +                      "description": "Pass/fail criteria used to evaluate the outcome",
        +                      "type": "string"
        +                    },
        +                    "description": {
        +                      "description": "Human-readable description of the expected outcome",
        +                      "type": "string"
        +                    }
        +                  },
        +                  "required": [
        +                    "description",
        +                    "criteria"
        +                  ],
        +                  "type": "object"
        +                },
        +                "type": "array"
        +              },
        +              "browserProvider": {
        +                "description": "Browser infrastructure provider",
        +                "enum": [
        +                  "browserbase",
        +                  "browser-use"
        +                ],
        +                "type": "string"
        +              },
        +              "evaluationSchemaId": {
        +                "description": "ID of the evaluation schema to apply to runs of this agent",
        +                "type": "string"
        +              },
        +              "supervisedMode": {
        +                "description": "Run the agent under Duvo's permission classifier: every tool call is classified as allow/deny/ask, with 'ask' routed to human-in-the-loop approval. Mutually exclusive with browsing and computer-use connections.",
        +                "type": "boolean"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "plugins": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Plugins to load — either a built-in plugin name (e.g. \"code-review\") or a GitHub URL (e.g. \"https://github.com/owner/repo\")"
        +          },
        +          "skills": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "IDs of skills (team or system) that should be available to the agent"
        +          },
        +          "subAgents": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "format": "uuid",
        +                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Retired — Sub-Assignments was removed. Accepted for backwards compatibility and ignored."
        +          }
        +        },
        +        "required": [
        +          "models",
        +          "input"
        +        ],
        +        "type": "object"
        +      },
        +      "version": {
        +        "const": "v2",
        +        "description": "Schema version discriminator — must be \"v2\" for the current schema",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "version",
        +      "data"
        +    ],
        +    "type": "object"
        +  },
        +  {
        +    "properties": {
        +      "data": {
        +        "description": "Code step configuration payload",
        +        "properties": {
        +          "files": {
        +            "anyOf": [
        +              {
        +                "items": {
        +                  "type": "string"
        +                },
        +                "type": "array"
        +              },
        +              {
        +                "type": "null"
        +              }
        +            ],
        +            "default": [],
        +            "description": "Team file paths this step can read at run time"
        +          },
        +          "handoverRequired": {
        +            "default": false,
        +            "description": "When the step declares handover options, whether a run that exits cleanly without requesting one fails. Ignored when the step declares no options.",
        +            "type": "boolean"
        +          },
        +          "language": {
        +            "description": "Language the step's program is written in",
        +            "enum": [
        +              "python"
        +            ],
        +            "type": "string"
        +          },
        +          "maxConcurrency": {
        +            "description": "Most runs of this step that may be in flight at once on one queue, on top of the queue's own concurrency. Absent means only the queue's limit applies. Every claim enforces it; only cases handed to the step (handover, postpone, reprocess) are also kept out of the queue's free slots while the step is full. Cases a trigger or a revision route sends straight to a capped step can still take queue slots and wait there, delaying other steps on the same queue.",
        +            "exclusiveMinimum": 0,
        +            "maximum": 1000,
        +            "type": "integer"
        +          },
        +          "source": {
        +            "description": "Where the step's program comes from",
        +            "oneOf": [
        +              {
        +                "properties": {
        +                  "code": {
        +                    "description": "Program held in the build config. Written to `main.py` and run with `python main.py`.",
        +                    "minLength": 1,
        +                    "type": "string"
        +                  },
        +                  "kind": {
        +                    "const": "inline",
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "kind",
        +                  "code"
        +                ],
        +                "type": "object"
        +              },
        +              {
        +                "properties": {
        +                  "bundle": {
        +                    "description": "The program's files, as a content-addressed manifest",
        +                    "properties": {
        +                      "bucket": {
        +                        "description": "GCS bucket the bundle's blobs are stored in",
        +                        "minLength": 1,
        +                        "type": "string"
        +                      },
        +                      "files": {
        +                        "description": "The program's files, one manifest entry each",
        +                        "items": {
        +                          "properties": {
        +                            "path": {
        +                              "description": "Path the file is materialised at, relative to the work dir",
        +                              "minLength": 1,
        +                              "type": "string"
        +                            },
        +                            "sha256": {
        +                              "description": "Digest of the file's bytes, and the key its blob is stored at",
        +                              "maxLength": 64,
        +                              "minLength": 64,
        +                              "pattern": "^[0-9a-f]{64}$",
        +                              "type": "string"
        +                            },
        +                            "sizeBytes": {
        +                              "description": "UTF-8 byte length of the file's contents",
        +                              "maximum": 131072,
        +                              "minimum": 0,
        +                              "type": "integer"
        +                            }
        +                          },
        +                          "required": [
        +                            "path",
        +                            "sha256",
        +                            "sizeBytes"
        +                          ],
        +                          "type": "object"
        +                        },
        +                        "maxItems": 200,
        +                        "type": "array"
        +                      }
        +                    },
        +                    "required": [
        +                      "bucket",
        +                      "files"
        +                    ],
        +                    "type": "object"
        +                  },
        +                  "kind": {
        +                    "const": "files",
        +                    "type": "string"
        +                  },
        +                  "startCommand": {
        +                    "description": "Command run from the root of the step's file system, e.g. \"python main.py\".",
        +                    "maxLength": 2000,
        +                    "minLength": 1,
        +                    "type": "string"
        +                  }
        +                },
        +                "required": [
        +                  "kind",
        +                  "startCommand"
        +                ],
        +                "type": "object"
        +              }
        +            ]
        +          },
        +          "timeoutMs": {
        +            "default": 600000,
        +            "description": "Wall-clock budget for one execution of the step",
        +            "exclusiveMinimum": 0,
        +            "maximum": 3600000,
        +            "type": "integer"
        +          }
        +        },
        +        "required": [
        +          "language",
        +          "source"
        +        ],
        +        "type": "object"
        +      },
        +      "version": {
        +        "const": "v1",
        +        "description": "Schema version discriminator — must be \"v1\" for the current code-step schema",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "version",
        +      "data"
        +    ],
        +    "type": "object"
        +  }
        +]
    • ChangedstartRun1 field changed
      • changedInput schema / properties / webhook_url / description
        Previous value: -"Webhook URL to POST events to (human_request, run_completed, run_failed, run_interrupted)"New value: +"Webhook URL to POST events to (human_request, run_completed, run_failed, run_interrupted, run_expired)"

Related MCP Connectors

Related MCP Servers

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources