diff --git a/packages/paperclip-runner/src/protocol-actions/collaboration-contracts.test.ts b/packages/paperclip-runner/src/protocol-actions/collaboration-contracts.test.ts new file mode 100644 index 0000000000..fa22566b60 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/collaboration-contracts.test.ts @@ -0,0 +1,76 @@ +import Ajv2020 from "ajv/dist/2020.js"; +import { describe, expect, it } from "vitest"; + +import { PAPERCLIP_COLLABORATION_PROTOCOL_ACTIONS } from "./collaboration.js"; + +describe("collaboration Paperclip protocol action contracts", () => { + const ajv = new Ajv2020({ allErrors: true, allowUnionTypes: true, strict: false }); + + it.each(PAPERCLIP_COLLABORATION_PROTOCOL_ACTIONS.map((action) => [action.id, action] as const))( + "%s has immutable metadata and schema-valid examples", + (operationId, action) => { + expect(action.canonical.operationId).toBe(operationId); + expect(action.canonical.placement).toBe("optional_agent_tool"); + expect(action.examples.call.operationId).toBe(operationId); + expect(action.examples.success.operationId).toBe(operationId); + expect(Object.isFrozen(action)).toBe(true); + expect(Object.isFrozen(action.canonical)).toBe(true); + + expect(action.live !== null || action.scenario !== null).toBe(true); + + if (action.live !== null) { + expect( + ajv.validate(action.live.descriptor.inputSchema, action.examples.call.input), + JSON.stringify(ajv.errors), + ).toBe(true); + expect( + ajv.validate(action.live.descriptor.outputSchema, action.examples.success.result), + JSON.stringify(ajv.errors), + ).toBe(true); + } + + if (action.scenario !== null) { + const scenarioProperties = action.scenario.descriptor.inputSchema.properties ?? {}; + const callEntries = Object.entries(action.examples.call.input); + const outOfBandKeys = callEntries + .map(([key]) => key) + .filter((key) => !(key in scenarioProperties)); + // Scenario mutation idempotency is carried by the invocation envelope, + // not the operation input. No other example field may be omitted. + expect(outOfBandKeys).toEqual( + "idempotencyKey" in action.examples.call.input ? ["idempotencyKey"] : [], + ); + const scenarioInput = Object.fromEntries( + callEntries.filter(([key]) => key !== "idempotencyKey"), + ); + const scenarioOutput = action.live === null + ? action.examples.success.result + : { + schema: "paperclip.capability.tool-result.v1", + ok: true, + operationId, + operationResultId: "example-result", + value: action.examples.success.result, + commandResult: null, + authorization: {}, + }; + expect(scenarioOutput.operationId).toBe(operationId); + + expect( + ajv.validate(action.scenario.descriptor.inputSchema, scenarioInput), + JSON.stringify(ajv.errors), + ).toBe(true); + expect( + ajv.validate(action.scenario.descriptor.outputSchema, scenarioOutput), + JSON.stringify(ajv.errors), + ).toBe(true); + expect( + ajv.validate(action.scenario.descriptor.outputSchema, { + ...scenarioOutput, + operationId: `${operationId}_mismatch`, + }), + ).toBe(false); + } + }, + ); +}); diff --git a/packages/paperclip-runner/src/protocol-actions/collaboration.ts b/packages/paperclip-runner/src/protocol-actions/collaboration.ts new file mode 100644 index 0000000000..fab0f73d23 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/collaboration.ts @@ -0,0 +1,31 @@ +import { commentOnApprovalAction } from "./comment-on-approval.js"; +import { createTaskAction } from "./create-task.js"; +import { decideApprovalAction } from "./decide-approval.js"; +import { getAgentAction } from "./get-agent.js"; +import { getApprovalAction } from "./get-approval.js"; +import { getApprovalContextAction } from "./get-approval-context.js"; +import { listAgentsAction } from "./list-agents.js"; +import { listApprovalsAction } from "./list-approvals.js"; +import { listGoalsAction } from "./list-goals.js"; +import { listProjectsAction } from "./list-projects.js"; +import { requestApprovalAction } from "./request-approval.js"; +import { searchTasksAction } from "./search-tasks.js"; +import { setDependenciesAction } from "./set-dependencies.js"; +import { deepFreezeProtocolAction } from "./freeze.js"; + +/** Optional discovery, delegation, dependency, and governance actions. */ +export const PAPERCLIP_COLLABORATION_PROTOCOL_ACTIONS = deepFreezeProtocolAction([ + commentOnApprovalAction, + createTaskAction, + decideApprovalAction, + getAgentAction, + getApprovalAction, + getApprovalContextAction, + listAgentsAction, + listApprovalsAction, + listGoalsAction, + listProjectsAction, + requestApprovalAction, + searchTasksAction, + setDependenciesAction, +] as const); diff --git a/packages/paperclip-runner/src/protocol-actions/comment-on-approval.ts b/packages/paperclip-runner/src/protocol-actions/comment-on-approval.ts new file mode 100644 index 0000000000..a6c14490ba --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/comment-on-approval.ts @@ -0,0 +1,237 @@ +/** Canonical definition and documentation for `comment_on_approval`. */ +export const commentOnApprovalAction = { + "id": "comment_on_approval", + "canonical": { + "operationId": "comment_on_approval", + "surfaces": [ + "scenario", + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": "governance", + "requiredClaims": [ + "governance:approvals:comment" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "governance", + "idempotency": "required", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "approval lifecycle plus governed-wait continuation and audit events", + "prpBindingStatus": "audit_pending", + "legacyAliases": [] + }, + "documentation": { + "title": "Comment on approval", + "description": "Add a durable comment to a mock approval.", + "note": null + }, + "examples": { + "call": { + "operationId": "comment_on_approval", + "input": { + "idempotencyKey": "example", + "approvalId": "example", + "body": "example" + } + }, + "success": { + "ok": true, + "operationId": "comment_on_approval", + "result": { + "commandId": "example", + "disposition": "applied", + "stateRevision": 1, + "entityRefs": [ + "example" + ], + "scheduledWakeIds": [ + "example" + ] + } + } + }, + "live": { + "order": 25, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "comment_on_approval", + "version": 1, + "title": "Comment on approval", + "description": "Add a durable comment to a mock approval.", + "exposure": "optional", + "requiredClaims": [ + "governance:approvals:comment" + ], + "allowedModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": { + "idempotencyKey": { + "type": "string", + "description": "Caller-stable retry key.", + "minLength": 1, + "maxLength": 240 + }, + "approvalId": { + "type": "string", + "description": "Mock approval id.", + "minLength": 1, + "maxLength": 200 + }, + "body": { + "type": "string", + "description": "Approval comment.", + "minLength": 1, + "maxLength": 20000 + } + }, + "required": [ + "idempotencyKey", + "approvalId", + "body" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "commandId": { + "type": "string", + "description": "Stable mock command identifier.", + "minLength": 1, + "maxLength": 200 + }, + "disposition": { + "enum": [ + "applied", + "duplicate" + ] + }, + "stateRevision": { + "type": "integer", + "minimum": 0 + }, + "entityRefs": { + "type": "array", + "description": "Mock entities affected by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + }, + "scheduledWakeIds": { + "type": "array", + "description": "Wake identifiers scheduled by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + } + }, + "required": [ + "commandId", + "disposition", + "stateRevision", + "entityRefs", + "scheduledWakeIds" + ], + "additionalProperties": false + } + } + }, + "scenario": { + "order": 23, + "descriptor": { + "operationId": "comment_on_approval", + "version": 1, + "title": "Comment On Approval", + "description": "Comment On Approval through the Capability governance capability set.", + "inputSchema": { + "type": "object", + "properties": { + "approvalId": { + "type": "string", + "minLength": 1 + }, + "body": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "approvalId", + "body" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "comment_on_approval" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "governance", + "requiredClaims": [ + "governance:approvals:comment" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "governance", + "idempotency": "required", + "redaction": [], + "mockCommandMapping": { + "kind": "semantic_command", + "commandKind": "comment_on_approval" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/create-task.ts b/packages/paperclip-runner/src/protocol-actions/create-task.ts new file mode 100644 index 0000000000..cf47440144 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/create-task.ts @@ -0,0 +1,289 @@ +/** Canonical definition and documentation for `create_task`. */ +export const createTaskAction = { + "id": "create_task", + "canonical": { + "operationId": "create_task", + "surfaces": [ + "scenario", + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": "delegation_dependencies", + "requiredClaims": [ + "delegation:tasks:create" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "company_write", + "idempotency": "required", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "issues.createChild", + "prpEvidence": "semantic-operation item event plus company-entity state diff and audit record", + "prpBindingStatus": "bound", + "legacyAliases": [ + "mcp:paperclipCreateIssue" + ] + }, + "documentation": { + "title": "Create child task", + "description": "Create one durable standard child under the active task.", + "note": null + }, + "examples": { + "call": { + "operationId": "create_task", + "input": { + "idempotencyKey": "example", + "title": "example" + } + }, + "success": { + "ok": true, + "operationId": "create_task", + "result": { + "commandId": "example", + "disposition": "applied", + "stateRevision": 1, + "entityRefs": [ + "example" + ], + "scheduledWakeIds": [ + "example" + ], + "task": { + "id": "example", + "identifier": "EX-2", + "parentId": "example-parent", + "status": "todo", + "assigneeActorId": "example-agent" + } + } + } + }, + "live": { + "order": 22, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "create_task", + "version": 1, + "title": "Create child task", + "description": "Create one durable standard child under the active task. Use only when a real ownership, parallelism, dependency, review, or lifecycle boundary justifies delegation.", + "exposure": "optional", + "requiredClaims": [ + "delegation:tasks:create" + ], + "allowedModes": [ + "standard", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": { + "idempotencyKey": { + "type": "string", + "description": "Caller-stable retry key.", + "minLength": 1, + "maxLength": 240 + }, + "title": { + "type": "string", + "description": "Child task title.", + "minLength": 1, + "maxLength": 500 + }, + "description": { + "type": [ + "string", + "null" + ], + "description": "Child task description.", + "maxLength": 20000 + }, + "assigneeActorId": { + "type": [ + "string", + "null" + ], + "description": "Optional agent assignee. Omit to assign the current agent.", + "maxLength": 20000 + }, + "priority": { + "enum": [ + "critical", + "high", + "medium", + "low" + ] + }, + "blockedByTaskIds": { + "type": "array", + "description": "Initial blocker task ids.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + } + }, + "required": [ + "idempotencyKey", + "title" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "commandId": { + "type": "string", + "description": "Stable mock command identifier.", + "minLength": 1, + "maxLength": 200 + }, + "disposition": { + "enum": [ + "applied", + "duplicate" + ] + }, + "stateRevision": { + "type": "integer", + "minimum": 0 + }, + "entityRefs": { + "type": "array", + "description": "Mock entities affected by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + }, + "scheduledWakeIds": { + "type": "array", + "description": "Wake identifiers scheduled by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + }, + "task": { + "type": "object", + "properties": { + "id": { "type": "string", "minLength": 1 }, + "identifier": { "type": ["string", "null"] }, + "parentId": { "type": "string", "minLength": 1 }, + "status": { "type": "string", "minLength": 1 }, + "assigneeActorId": { "type": ["string", "null"] } + }, + "required": ["id", "identifier", "parentId", "status", "assigneeActorId"], + "additionalProperties": false + } + }, + "required": [ + "commandId", + "disposition", + "stateRevision", + "entityRefs", + "scheduledWakeIds", + "task" + ], + "additionalProperties": false + } + } + }, + "scenario": { + "order": 18, + "descriptor": { + "operationId": "create_task", + "version": 1, + "title": "Create Task", + "description": "Create Task through the Capability delegation dependencies capability set.", + "inputSchema": { + "type": "object", + "properties": { + "title": { + "type": "string", + "minLength": 1 + }, + "description": { + "type": "string" + }, + "assigneeActorId": { + "type": "string" + }, + "priority": { + "type": "string" + }, + "blockedByTaskIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "title" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "create_task" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "delegation_dependencies", + "requiredClaims": [ + "delegation:tasks:create" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "company_write", + "idempotency": "required", + "redaction": [], + "mockCommandMapping": { + "kind": "semantic_command", + "commandKind": "create_task" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/decide-approval.ts b/packages/paperclip-runner/src/protocol-actions/decide-approval.ts new file mode 100644 index 0000000000..8e4df7a919 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/decide-approval.ts @@ -0,0 +1,264 @@ +/** Canonical definition and documentation for `decide_approval`. */ +export const decideApprovalAction = { + "id": "decide_approval", + "canonical": { + "operationId": "decide_approval", + "surfaces": [ + "scenario", + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": "governance", + "requiredClaims": [ + "governance:approvals:decide" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "allowedRoles": [ + "board", + "approver", + "security" + ], + "sideEffectClass": "governance", + "idempotency": "required", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "approval lifecycle plus governed-wait continuation and audit events", + "prpBindingStatus": "audit_pending", + "legacyAliases": [] + }, + "documentation": { + "title": "Decide approval", + "description": "Decide a mock approval as an explicitly authorized approver.", + "note": null + }, + "examples": { + "call": { + "operationId": "decide_approval", + "input": { + "idempotencyKey": "example", + "approvalId": "example", + "decision": "approved", + "note": "example" + } + }, + "success": { + "ok": true, + "operationId": "decide_approval", + "result": { + "commandId": "example", + "disposition": "applied", + "stateRevision": 1, + "entityRefs": [ + "example" + ], + "scheduledWakeIds": [ + "example" + ] + } + } + }, + "live": { + "order": 24, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "decide_approval", + "version": 1, + "title": "Decide approval", + "description": "Decide a mock approval as an explicitly authorized approver.", + "exposure": "optional", + "requiredClaims": [ + "governance:approvals:decide" + ], + "allowedModes": [ + "standard", + "skill_test" + ], + "allowedRoles": [ + "board", + "approver", + "security" + ], + "inputSchema": { + "type": "object", + "properties": { + "idempotencyKey": { + "type": "string", + "description": "Caller-stable retry key.", + "minLength": 1, + "maxLength": 240 + }, + "approvalId": { + "type": "string", + "description": "Mock approval id.", + "minLength": 1, + "maxLength": 200 + }, + "decision": { + "enum": [ + "approved", + "rejected", + "cancelled" + ] + }, + "note": { + "type": "string", + "description": "Decision note.", + "minLength": 1, + "maxLength": 20000 + } + }, + "required": [ + "idempotencyKey", + "approvalId", + "decision", + "note" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "commandId": { + "type": "string", + "description": "Stable mock command identifier.", + "minLength": 1, + "maxLength": 200 + }, + "disposition": { + "enum": [ + "applied", + "duplicate" + ] + }, + "stateRevision": { + "type": "integer", + "minimum": 0 + }, + "entityRefs": { + "type": "array", + "description": "Mock entities affected by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + }, + "scheduledWakeIds": { + "type": "array", + "description": "Wake identifiers scheduled by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + } + }, + "required": [ + "commandId", + "disposition", + "stateRevision", + "entityRefs", + "scheduledWakeIds" + ], + "additionalProperties": false + } + } + }, + "scenario": { + "order": 22, + "descriptor": { + "operationId": "decide_approval", + "version": 1, + "title": "Decide Approval", + "description": "Decide Approval through the Capability governance capability set.", + "inputSchema": { + "type": "object", + "properties": { + "approvalId": { + "type": "string", + "minLength": 1 + }, + "decision": { + "type": "string", + "enum": [ + "approved", + "rejected", + "cancelled" + ] + }, + "note": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "approvalId", + "decision", + "note" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "decide_approval" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "governance", + "requiredClaims": [ + "governance:approvals:decide" + ], + "allowedRoles": [ + "board", + "approver", + "security" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "governance", + "idempotency": "required", + "redaction": [], + "mockCommandMapping": { + "kind": "semantic_command", + "commandKind": "decide_approval" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/get-agent.ts b/packages/paperclip-runner/src/protocol-actions/get-agent.ts new file mode 100644 index 0000000000..2320ad4256 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/get-agent.ts @@ -0,0 +1,90 @@ +/** Canonical definition and documentation for `get_agent`. */ +export const getAgentAction = { + "id": "get_agent", + "canonical": { + "operationId": "get_agent", + "surfaces": [ + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": null, + "requiredClaims": [ + "discovery:agents:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "read projection surfaced via a tool-result item event; no control-plane state diff", + "prpBindingStatus": "audit_pending", + "legacyAliases": [ + "mcp:paperclipGetAgent" + ], + "note": "Live-only single-actor read; the scenario suite covers actor discovery through list_agents." + }, + "documentation": { + "title": "Get company agent", + "description": "Read one redacted mock actor profile.", + "note": "Live-only single-actor read; the scenario suite covers actor discovery through list_agents." + }, + "examples": { + "call": { + "operationId": "get_agent", + "input": { + "actorId": "example" + } + }, + "success": { + "ok": true, + "operationId": "get_agent", + "result": {} + } + }, + "live": { + "order": 14, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "get_agent", + "version": 1, + "title": "Get company agent", + "description": "Read one redacted mock actor profile.", + "exposure": "optional", + "requiredClaims": [ + "discovery:agents:read" + ], + "allowedModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": { + "actorId": { + "type": "string", + "description": "Mock actor id.", + "minLength": 1, + "maxLength": 200 + } + }, + "required": [ + "actorId" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "additionalProperties": true + } + } + }, + "scenario": null +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/get-approval-context.ts b/packages/paperclip-runner/src/protocol-actions/get-approval-context.ts new file mode 100644 index 0000000000..7cbc9650e7 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/get-approval-context.ts @@ -0,0 +1,88 @@ +/** Canonical definition and documentation for `get_approval_context`. */ +export const getApprovalContextAction = { + "id": "get_approval_context", + "canonical": { + "operationId": "get_approval_context", + "surfaces": [ + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": null, + "requiredClaims": [ + "governance:approvals:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "read projection surfaced via a tool-result item event; no control-plane state diff", + "prpBindingStatus": "audit_pending", + "legacyAliases": [], + "note": "Live-only approval-plus-linked-tasks read; no scenario counterpart." + }, + "documentation": { + "title": "Get approval context", + "description": "Read one approval, its comments, and linked mock tasks.", + "note": "Live-only approval-plus-linked-tasks read; no scenario counterpart." + }, + "examples": { + "call": { + "operationId": "get_approval_context", + "input": { + "approvalId": "example" + } + }, + "success": { + "ok": true, + "operationId": "get_approval_context", + "result": {} + } + }, + "live": { + "order": 18, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "get_approval_context", + "version": 1, + "title": "Get approval context", + "description": "Read one approval, its comments, and linked mock tasks.", + "exposure": "optional", + "requiredClaims": [ + "governance:approvals:read" + ], + "allowedModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": { + "approvalId": { + "type": "string", + "description": "Mock approval id.", + "minLength": 1, + "maxLength": 200 + } + }, + "required": [ + "approvalId" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "additionalProperties": true + } + } + }, + "scenario": null +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/get-approval.ts b/packages/paperclip-runner/src/protocol-actions/get-approval.ts new file mode 100644 index 0000000000..c66dbd7dfd --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/get-approval.ts @@ -0,0 +1,88 @@ +/** Canonical definition and documentation for `get_approval`. */ +export const getApprovalAction = { + "id": "get_approval", + "canonical": { + "operationId": "get_approval", + "surfaces": [ + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": null, + "requiredClaims": [ + "governance:approvals:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "read projection surfaced via a tool-result item event; no control-plane state diff", + "prpBindingStatus": "audit_pending", + "legacyAliases": [], + "note": "Live-only single-approval read; the scenario suite covers approvals through list_approvals." + }, + "documentation": { + "title": "Get approval", + "description": "Read one mock approval without protected data.", + "note": "Live-only single-approval read; the scenario suite covers approvals through list_approvals." + }, + "examples": { + "call": { + "operationId": "get_approval", + "input": { + "approvalId": "example" + } + }, + "success": { + "ok": true, + "operationId": "get_approval", + "result": {} + } + }, + "live": { + "order": 17, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "get_approval", + "version": 1, + "title": "Get approval", + "description": "Read one mock approval without protected data.", + "exposure": "optional", + "requiredClaims": [ + "governance:approvals:read" + ], + "allowedModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": { + "approvalId": { + "type": "string", + "description": "Mock approval id.", + "minLength": 1, + "maxLength": 200 + } + }, + "required": [ + "approvalId" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "additionalProperties": true + } + } + }, + "scenario": null +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/inspect-operation-result.ts b/packages/paperclip-runner/src/protocol-actions/inspect-operation-result.ts index fc3c04f915..e496abe3be 100644 --- a/packages/paperclip-runner/src/protocol-actions/inspect-operation-result.ts +++ b/packages/paperclip-runner/src/protocol-actions/inspect-operation-result.ts @@ -94,8 +94,7 @@ export const inspectOperationResultAction = { "type": "boolean" }, "operationId": { - "type": "string", - "minLength": 1 + "const": "inspect_operation_result" }, "operationResultId": { "type": "string", diff --git a/packages/paperclip-runner/src/protocol-actions/list-agents.ts b/packages/paperclip-runner/src/protocol-actions/list-agents.ts new file mode 100644 index 0000000000..8a77bfbf04 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/list-agents.ts @@ -0,0 +1,145 @@ +/** Canonical definition and documentation for `list_agents`. */ +export const listAgentsAction = { + "id": "list_agents", + "canonical": { + "operationId": "list_agents", + "surfaces": [ + "scenario", + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": "discovery", + "requiredClaims": [ + "discovery:agents:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "read projection surfaced via a tool-result item event; no control-plane state diff", + "prpBindingStatus": "audit_pending", + "legacyAliases": [ + "mcp:paperclipListAgents" + ] + }, + "documentation": { + "title": "List company agents", + "description": "List redacted mock actor profiles.", + "note": null + }, + "examples": { + "call": { + "operationId": "list_agents", + "input": {} + }, + "success": { + "ok": true, + "operationId": "list_agents", + "result": {} + } + }, + "live": { + "order": 13, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "list_agents", + "version": 1, + "title": "List company agents", + "description": "List redacted mock actor profiles.", + "exposure": "optional", + "requiredClaims": [ + "discovery:agents:read" + ], + "allowedModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "additionalProperties": true + } + } + }, + "scenario": { + "order": 15, + "descriptor": { + "operationId": "list_agents", + "version": 1, + "title": "List Agents", + "description": "List Agents through the Capability discovery capability set.", + "inputSchema": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "list_agents" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "discovery", + "requiredClaims": [ + "discovery:agents:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "redaction": [], + "mockCommandMapping": { + "kind": "snapshot_read", + "projection": "company_actors" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/list-approvals.ts b/packages/paperclip-runner/src/protocol-actions/list-approvals.ts new file mode 100644 index 0000000000..29b4b08663 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/list-approvals.ts @@ -0,0 +1,143 @@ +/** Canonical definition and documentation for `list_approvals`. */ +export const listApprovalsAction = { + "id": "list_approvals", + "canonical": { + "operationId": "list_approvals", + "surfaces": [ + "scenario", + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": "governance", + "requiredClaims": [ + "governance:approvals:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "read projection surfaced via a tool-result item event; no control-plane state diff", + "prpBindingStatus": "audit_pending", + "legacyAliases": [] + }, + "documentation": { + "title": "List approvals", + "description": "List mock approvals in the run company.", + "note": null + }, + "examples": { + "call": { + "operationId": "list_approvals", + "input": {} + }, + "success": { + "ok": true, + "operationId": "list_approvals", + "result": {} + } + }, + "live": { + "order": 16, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "list_approvals", + "version": 1, + "title": "List approvals", + "description": "List mock approvals in the run company.", + "exposure": "optional", + "requiredClaims": [ + "governance:approvals:read" + ], + "allowedModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "additionalProperties": true + } + } + }, + "scenario": { + "order": 20, + "descriptor": { + "operationId": "list_approvals", + "version": 1, + "title": "List Approvals", + "description": "List Approvals through the Capability governance capability set.", + "inputSchema": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "list_approvals" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "governance", + "requiredClaims": [ + "governance:approvals:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "redaction": [], + "mockCommandMapping": { + "kind": "snapshot_read", + "projection": "company_approvals" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/list-goals.ts b/packages/paperclip-runner/src/protocol-actions/list-goals.ts new file mode 100644 index 0000000000..8956b41e8b --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/list-goals.ts @@ -0,0 +1,118 @@ +/** Canonical definition and documentation for `list_goals`. */ +export const listGoalsAction = { + "id": "list_goals", + "canonical": { + "operationId": "list_goals", + "surfaces": [ + "scenario" + ], + "placement": "optional_agent_tool", + "optionalGroup": "discovery", + "requiredClaims": [ + "discovery:goals:read" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "disabledByDefault": false, + "realBindingStatus": "scenario_mock", + "realServiceBinding": "unbound", + "prpEvidence": "read projection surfaced via a tool-result item event; no control-plane state diff", + "prpBindingStatus": "audit_pending", + "legacyAliases": [], + "note": "Scenario/eval-only discovery via mock extension; no live dispatcher binding yet." + }, + "documentation": { + "title": "List Goals", + "description": "List Goals through the Capability discovery capability set.", + "note": "Scenario/eval-only discovery via mock extension; no live dispatcher binding yet." + }, + "examples": { + "call": { + "operationId": "list_goals", + "input": {} + }, + "success": { + "ok": true, + "operationId": "list_goals", + "result": { + "schema": "paperclip.capability.tool-result.v1", + "ok": true, + "operationId": "list_goals", + "operationResultId": "example", + "value": "example", + "commandResult": "example", + "authorization": "example" + } + } + }, + "live": null, + "scenario": { + "order": 17, + "descriptor": { + "operationId": "list_goals", + "version": 1, + "title": "List Goals", + "description": "List Goals through the Capability discovery capability set.", + "inputSchema": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "list_goals" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "discovery", + "requiredClaims": [ + "discovery:goals:read" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "redaction": [], + "mockCommandMapping": { + "kind": "mock_extension", + "extension": "discovery.goals" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/list-projects.ts b/packages/paperclip-runner/src/protocol-actions/list-projects.ts new file mode 100644 index 0000000000..ff4b117dce --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/list-projects.ts @@ -0,0 +1,118 @@ +/** Canonical definition and documentation for `list_projects`. */ +export const listProjectsAction = { + "id": "list_projects", + "canonical": { + "operationId": "list_projects", + "surfaces": [ + "scenario" + ], + "placement": "optional_agent_tool", + "optionalGroup": "discovery", + "requiredClaims": [ + "discovery:projects:read" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "disabledByDefault": false, + "realBindingStatus": "scenario_mock", + "realServiceBinding": "unbound", + "prpEvidence": "read projection surfaced via a tool-result item event; no control-plane state diff", + "prpBindingStatus": "audit_pending", + "legacyAliases": [], + "note": "Scenario/eval-only discovery via mock extension; no live dispatcher binding yet." + }, + "documentation": { + "title": "List Projects", + "description": "List Projects through the Capability discovery capability set.", + "note": "Scenario/eval-only discovery via mock extension; no live dispatcher binding yet." + }, + "examples": { + "call": { + "operationId": "list_projects", + "input": {} + }, + "success": { + "ok": true, + "operationId": "list_projects", + "result": { + "schema": "paperclip.capability.tool-result.v1", + "ok": true, + "operationId": "list_projects", + "operationResultId": "example", + "value": "example", + "commandResult": "example", + "authorization": "example" + } + } + }, + "live": null, + "scenario": { + "order": 16, + "descriptor": { + "operationId": "list_projects", + "version": 1, + "title": "List Projects", + "description": "List Projects through the Capability discovery capability set.", + "inputSchema": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "list_projects" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "discovery", + "requiredClaims": [ + "discovery:projects:read" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "redaction": [], + "mockCommandMapping": { + "kind": "mock_extension", + "extension": "discovery.projects" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/request-approval.ts b/packages/paperclip-runner/src/protocol-actions/request-approval.ts new file mode 100644 index 0000000000..5f98ea1ef6 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/request-approval.ts @@ -0,0 +1,226 @@ +/** Canonical definition and documentation for `request_approval`. */ +export const requestApprovalAction = { + "id": "request_approval", + "canonical": { + "operationId": "request_approval", + "surfaces": [ + "scenario", + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": "governance", + "requiredClaims": [ + "governance:approvals:request" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "governance", + "idempotency": "required", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "approval lifecycle plus governed-wait continuation and audit events", + "prpBindingStatus": "audit_pending", + "legacyAliases": [] + }, + "documentation": { + "title": "Request approval", + "description": "Create a governed mock approval and waiting posture.", + "note": null + }, + "examples": { + "call": { + "operationId": "request_approval", + "input": { + "idempotencyKey": "example", + "approvalType": "example", + "payload": {} + } + }, + "success": { + "ok": true, + "operationId": "request_approval", + "result": { + "commandId": "example", + "disposition": "applied", + "stateRevision": 1, + "entityRefs": [ + "example" + ], + "scheduledWakeIds": [ + "example" + ] + } + } + }, + "live": { + "order": 23, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "request_approval", + "version": 1, + "title": "Request approval", + "description": "Create a governed mock approval and waiting posture.", + "exposure": "optional", + "requiredClaims": [ + "governance:approvals:request" + ], + "allowedModes": [ + "standard", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": { + "idempotencyKey": { + "type": "string", + "description": "Caller-stable retry key.", + "minLength": 1, + "maxLength": 240 + }, + "approvalType": { + "type": "string", + "description": "Stable approval type.", + "minLength": 1, + "maxLength": 200 + }, + "payload": { + "type": "object", + "additionalProperties": true + } + }, + "required": [ + "idempotencyKey", + "approvalType", + "payload" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "commandId": { + "type": "string", + "description": "Stable mock command identifier.", + "minLength": 1, + "maxLength": 200 + }, + "disposition": { + "enum": [ + "applied", + "duplicate" + ] + }, + "stateRevision": { + "type": "integer", + "minimum": 0 + }, + "entityRefs": { + "type": "array", + "description": "Mock entities affected by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + }, + "scheduledWakeIds": { + "type": "array", + "description": "Wake identifiers scheduled by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + } + }, + "required": [ + "commandId", + "disposition", + "stateRevision", + "entityRefs", + "scheduledWakeIds" + ], + "additionalProperties": false + } + } + }, + "scenario": { + "order": 21, + "descriptor": { + "operationId": "request_approval", + "version": 1, + "title": "Request Approval", + "description": "Request Approval through the Capability governance capability set.", + "inputSchema": { + "type": "object", + "properties": { + "approvalType": { + "type": "string", + "minLength": 1 + }, + "payload": {} + }, + "required": [ + "approvalType", + "payload" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "request_approval" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "governance", + "requiredClaims": [ + "governance:approvals:request" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "governance", + "idempotency": "required", + "redaction": [], + "mockCommandMapping": { + "kind": "semantic_command", + "commandKind": "request_approval" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/search-tasks.ts b/packages/paperclip-runner/src/protocol-actions/search-tasks.ts new file mode 100644 index 0000000000..4873fb42e2 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/search-tasks.ts @@ -0,0 +1,179 @@ +/** Canonical definition and documentation for `search_tasks`. */ +export const searchTasksAction = { + "id": "search_tasks", + "canonical": { + "operationId": "search_tasks", + "surfaces": [ + "scenario", + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": "discovery", + "requiredClaims": [ + "discovery:tasks:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "unbound", + "prpEvidence": "read projection surfaced via a tool-result item event; no control-plane state diff", + "prpBindingStatus": "audit_pending", + "legacyAliases": [ + "mcp:paperclipListIssues" + ] + }, + "documentation": { + "title": "Search company tasks", + "description": "Search mock tasks by text and status within the run company.", + "note": null + }, + "examples": { + "call": { + "operationId": "search_tasks", + "input": {} + }, + "success": { + "ok": true, + "operationId": "search_tasks", + "result": {} + } + }, + "live": { + "order": 15, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "search_tasks", + "version": 1, + "title": "Search company tasks", + "description": "Search mock tasks by text and status within the run company.", + "exposure": "optional", + "requiredClaims": [ + "discovery:tasks:read" + ], + "allowedModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": { + "query": { + "type": "string", + "maxLength": 500 + }, + "statuses": { + "type": "array", + "items": { + "enum": [ + "backlog", + "todo", + "in_progress", + "in_review", + "done", + "blocked", + "cancelled" + ] + }, + "maxItems": 7, + "uniqueItems": true + }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 200, + "default": 50 + } + }, + "required": [], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "additionalProperties": true + } + } + }, + "scenario": { + "order": 14, + "descriptor": { + "operationId": "search_tasks", + "version": 1, + "title": "Search Tasks", + "description": "Search Tasks through the Capability discovery capability set.", + "inputSchema": { + "type": "object", + "properties": { + "query": { + "type": "string" + }, + "status": { + "type": "string" + } + }, + "required": [], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "search_tasks" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "discovery", + "requiredClaims": [ + "discovery:tasks:read" + ], + "taskModes": [ + "standard", + "ask", + "planning", + "skill_test" + ], + "sideEffectClass": "read", + "idempotency": "none", + "redaction": [], + "mockCommandMapping": { + "kind": "snapshot_read", + "projection": "company_tasks" + } + } + } +} as const; diff --git a/packages/paperclip-runner/src/protocol-actions/set-dependencies.ts b/packages/paperclip-runner/src/protocol-actions/set-dependencies.ts new file mode 100644 index 0000000000..b011948bb6 --- /dev/null +++ b/packages/paperclip-runner/src/protocol-actions/set-dependencies.ts @@ -0,0 +1,227 @@ +/** Canonical definition and documentation for `set_dependencies`. */ +export const setDependenciesAction = { + "id": "set_dependencies", + "canonical": { + "operationId": "set_dependencies", + "surfaces": [ + "scenario", + "live" + ], + "placement": "optional_agent_tool", + "optionalGroup": "delegation_dependencies", + "requiredClaims": [ + "dependencies:write" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "company_write", + "idempotency": "required", + "disabledByDefault": false, + "realBindingStatus": "live_codex", + "realServiceBinding": "issues.update.blockedByIssueIds", + "prpEvidence": "semantic-operation item event plus company-entity state diff and audit record", + "prpBindingStatus": "bound", + "legacyAliases": [] + }, + "documentation": { + "title": "Set task dependencies", + "description": "Replace the active task's first-class blocker set.", + "note": null + }, + "examples": { + "call": { + "operationId": "set_dependencies", + "input": { + "idempotencyKey": "example", + "blockedByTaskIds": [ + "example" + ] + } + }, + "success": { + "ok": true, + "operationId": "set_dependencies", + "result": { + "commandId": "example", + "disposition": "applied", + "stateRevision": 1, + "entityRefs": [ + "example" + ], + "scheduledWakeIds": [ + "example" + ] + } + } + }, + "live": { + "order": 21, + "descriptor": { + "schema": "paperclip.semantic-tool.v1", + "operationId": "set_dependencies", + "version": 1, + "title": "Set task dependencies", + "description": "Replace the active task's first-class blocker set.", + "exposure": "optional", + "requiredClaims": [ + "dependencies:write" + ], + "allowedModes": [ + "standard", + "skill_test" + ], + "inputSchema": { + "type": "object", + "properties": { + "idempotencyKey": { + "type": "string", + "description": "Caller-stable retry key.", + "minLength": 1, + "maxLength": 240 + }, + "blockedByTaskIds": { + "type": "array", + "description": "Replacement blocker task ids.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + } + }, + "required": [ + "idempotencyKey", + "blockedByTaskIds" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "commandId": { + "type": "string", + "description": "Stable mock command identifier.", + "minLength": 1, + "maxLength": 200 + }, + "disposition": { + "enum": [ + "applied", + "duplicate" + ] + }, + "stateRevision": { + "type": "integer", + "minimum": 0 + }, + "entityRefs": { + "type": "array", + "description": "Mock entities affected by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + }, + "scheduledWakeIds": { + "type": "array", + "description": "Wake identifiers scheduled by the operation.", + "items": { + "type": "string", + "minLength": 1 + }, + "maxItems": 200, + "uniqueItems": true + } + }, + "required": [ + "commandId", + "disposition", + "stateRevision", + "entityRefs", + "scheduledWakeIds" + ], + "additionalProperties": false + } + } + }, + "scenario": { + "order": 19, + "descriptor": { + "operationId": "set_dependencies", + "version": 1, + "title": "Set Dependencies", + "description": "Set Dependencies through the Capability delegation dependencies capability set.", + "inputSchema": { + "type": "object", + "properties": { + "blockedByTaskIds": { + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + } + }, + "required": [ + "blockedByTaskIds" + ], + "additionalProperties": false + }, + "outputSchema": { + "type": "object", + "properties": { + "schema": { + "type": "string", + "enum": [ + "paperclip.capability.tool-result.v1" + ] + }, + "ok": { + "type": "boolean" + }, + "operationId": { + "const": "set_dependencies" + }, + "operationResultId": { + "type": "string", + "minLength": 1 + }, + "value": {}, + "commandResult": {}, + "authorization": {} + }, + "required": [ + "schema", + "ok", + "operationId", + "operationResultId", + "value", + "commandResult", + "authorization" + ], + "additionalProperties": false + }, + "disposition": "optional_agent_tool", + "optionalGroup": "delegation_dependencies", + "requiredClaims": [ + "dependencies:write" + ], + "taskModes": [ + "standard", + "skill_test" + ], + "sideEffectClass": "company_write", + "idempotency": "required", + "redaction": [], + "mockCommandMapping": { + "kind": "semantic_command", + "commandKind": "set_dependencies" + } + } + } +} as const;