mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 17:45:53 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - The Runner gives agents tools to change company resources. > - Users need agents to save reusable skills during a task. > - A saved skill needs a visible result that users can inspect and edit. > - This pull request adds `create_skill` and a task feed card linked to Skill Studio. > - Users can open the saved skill from the task and edit the same resource. ## Linked Issues or Issue Description **Subsystem affected** Runner tools, company skill storage, task feed, and Skill Studio. **Problem or motivation** The Runner has no dedicated tool to create a company skill. A user cannot follow a creation result from the task feed to the saved skill. **Proposed solution** Add a company-scoped `create_skill` tool. Save the skill with the existing company policy. Add one creation card to the task. Open a named sidebar tab from that card. Let the user open the same skill in Skill Studio. **Alternatives considered** An agent can write a local file, but that file is not a company skill. A second document copy in the task would become stale after a Studio edit. The sidebar therefore reads the saved skill directly. **Roadmap alignment** This extends the shipped Skills Manager, Skill Studio, and Skills Store milestone. The maintainer requested and approved this scope. Search found no duplicate `create_skill` PR or issue. Related UI validation work: #8715. This PR does not change that validation display. ## What Changed - Add the real Runner tool, its contract, and its mock implementation. - Validate the complete SKILL.md and derive company, task, agent, and run identity from authentication. - Apply the existing company skill policy. Do not assign the skill to an agent. - Make keyed retries return one skill and one creation event. Reject conflicting retries. - Make concurrent file creation safe. Never replace an existing published skill during creation. - Add a creation card, a named sidebar tab, and an Open in Skill Studio action. - Show saved Studio edits when the user returns to the task. - Add storage, policy, mode, retry, UI, and Product E2E tests. Document the tool. - Fix deleted-name reuse, onboarding panel persistence, immediate feed refresh, and mock validation parity from review. - Serialize Studio file edits and renames with skill deletion and recreation. Reject stale editor requests before they can change a replacement skill. - Generate the standalone mock parser and validator from the production contract. Use portable UUIDs so the browser scenario bundle builds. ## Verification - All latest-head PR checks pass on `145dd76a5`, including all server shards, browser E2E, Runner verification, build, typecheck, and release dry run. Greptile: 5/5 with no open findings. An interrupted CI runner was retried successfully. - `pnpm -r typecheck`: passed. - `pnpm build`: passed. - `pnpm check:token-gates`: passed. - Review regressions: 73 storage tests, 6 real API tests, 63 UI tests, and 61 semantic runtime tests passed. Parser synchronization passed. - CI exposed existing fire-and-forget Sentry test races. Reproduced the resumption race locally, then synchronized the related sweep and finalizer assertions on the actual report; all 27 tests across the three affected files pass. - Runner scenario browser build and strict content-security-policy check: passed. - Runner suite: 2,012 tests passed; 10 skipped. - `pnpm test:run`: the general-server batch had 12,416 passes and two failures. The old tool-count assertion was fixed; all 16 authority tests then passed. The chat webhook test had a socket error; it passed four isolated reruns. - Both workspace test groups passed. The isolated route suites completed. Two socket failures in the initial route batches passed on individual reruns; all remaining 61 files passed. - Product E2E `create-skill-studio`: passed with local Codex and local ACPX Claude. - Manual browser test: submit a task, observe the real tool call and creation card, open the sidebar, edit in Studio, save, and return. The task reached Done. The saved second revision and sidebar tab survived a server restart. - The new companion headless Runner Eval passed. Companion coverage PR: https://github.com/paperclipai/paperclip-evals/pull/23. Daytona was not run because no immutable runner image was configured. ## Risks - Database writes and local file writes cannot share one transaction. Recovery accepts only an exact file-for-file retry after a database rollback. Conflicting files remain untouched. - The sidebar displays the current skill. The feed card remains the historical creation receipt. - No database migration, dependency, or workflow change is included. - Remote Daytona behavior still needs a run with a configured immutable image. ## Model Used OpenAI GPT-6 (`gpt-6-astra`) handled design, integration, review, and browser verification. OpenAI `gpt-5.6-luna` assisted with bounded implementation and eval work. Both used code execution and tool access. The host did not expose the context window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
372 lines
25 KiB
JSON
372 lines
25 KiB
JSON
{
|
|
"schemaVersion": 1,
|
|
"documentTitle": "Paperclip agent operation groups",
|
|
"evalRepositoryUrl": "https://github.com/paperclipai/paperclip-evals/blob/master/",
|
|
"prpEventFamilyDescriptions": {
|
|
"runner": "Runner connection, drain, and diagnostic lifecycle.",
|
|
"runtime": "Runner phase transitions.",
|
|
"sandbox": "Sandbox resource measurements.",
|
|
"workspace": "Workspace readiness.",
|
|
"harness": "Provider harness startup, readiness, exit, and diagnostics.",
|
|
"session": "Provider-neutral session open, resume, reconciliation, close, and failure.",
|
|
"turn": "Model turn submission through terminal turn disposition.",
|
|
"item": "Provider-neutral model/tool item lifecycle.",
|
|
"mcp_app": "MCP App discovery, initialization, tool, action, host-context, and teardown evidence.",
|
|
"runtime_request": "Runtime permission/input request lifecycle.",
|
|
"interaction": "Issue-thread interaction proposal, materialization, response, delivery, and rejection.",
|
|
"run": "Structured result negotiation and terminal run outcome.",
|
|
"attention": "Continuation and attention routing lifecycle.",
|
|
"work": "Recorded work-assessment evidence.",
|
|
"issue": "Issue-status decision proposal outcome and application evidence.",
|
|
"plan": "Complete provider-authored within-turn checklist snapshots, separate from durable Paperclip Plan documents.",
|
|
"tool": "Provider-neutral process, MCP, dynamic, and built-in execution activity.",
|
|
"research": "Provider-reported search, page-open, and in-page research activity.",
|
|
"delegation": "Child-agent delegation lifecycle and aggregate status.",
|
|
"model": "Requested/effective model routing and verification state.",
|
|
"context": "Context-window compaction markers without hidden summaries.",
|
|
"artifact": "Authorized artifact viewing and structured generated outputs.",
|
|
"review": "Provider review-mode state, separate from Paperclip authority.",
|
|
"hook": "Bounded provider hook lifecycle and blocking outcomes.",
|
|
"memory": "Authorized or unavailable memory citation references.",
|
|
"safety": "Provider safety review state attached to governed work.",
|
|
"terminal": "Content-free terminal input activity metadata.",
|
|
"wait": "Intentional provider waits, distinct from warm idle and human input.",
|
|
"provider": "Redacted provider notices and actionable warnings.",
|
|
"semantic_tool": "Canonical authorized Paperclip tool input and result evidence.",
|
|
"usage": "Provider/model-attributed usage and accounting boundaries."
|
|
},
|
|
"prpCommandFamilyDescriptions": {
|
|
"semantic_tool": "Returns an authorized, correlated Paperclip tool result to the provider through runnerd.",
|
|
"run": "Prepare or cancel a run.",
|
|
"session": "Open, snapshot, or close a normalized provider session.",
|
|
"turn": "Start, steer, interrupt, or stop a model turn.",
|
|
"request": "Resolve a pending runtime request.",
|
|
"interaction": "Acknowledge delivery of an interaction response.",
|
|
"runner": "Drain or shut down the runner process."
|
|
},
|
|
"optionalGrantGroups": [
|
|
{
|
|
"id": "discovery",
|
|
"description": "Company-visible task, agent, project, and goal discovery.",
|
|
"operationIds": ["search_tasks", "list_agents", "get_agent", "list_projects", "list_goals"]
|
|
},
|
|
{
|
|
"id": "projects",
|
|
"description": "Project creation and authorized repository discovery through the live company/run authority.",
|
|
"operationIds": ["create_project", "list_project_repositories"]
|
|
},
|
|
{
|
|
"id": "delegation_dependencies",
|
|
"description": "Create delegated work and maintain dependency edges.",
|
|
"operationIds": ["create_task", "set_dependencies"]
|
|
},
|
|
{
|
|
"id": "governance",
|
|
"description": "Read, request, comment on, and decide approvals under governed-action checks.",
|
|
"operationIds": ["list_approvals", "get_approval", "get_approval_context", "request_approval", "decide_approval", "comment_on_approval"]
|
|
},
|
|
{
|
|
"id": "cases",
|
|
"description": "Read and update case summaries without reusing issue-document authority.",
|
|
"operationIds": ["list_cases", "upsert_case"]
|
|
},
|
|
{
|
|
"id": "workspace_runtime",
|
|
"description": "Inspect and control the active issue workspace runtime.",
|
|
"operationIds": ["get_workspace_runtime", "control_workspace_service"]
|
|
},
|
|
{
|
|
"id": "wake_scheduling",
|
|
"description": "Schedule a bounded continuation wake when the current task owns the future check.",
|
|
"operationIds": ["schedule_wake"]
|
|
},
|
|
{
|
|
"id": "routines",
|
|
"description": "Inspect or manage company routines.",
|
|
"operationIds": ["list_routines", "manage_routine"]
|
|
},
|
|
{
|
|
"id": "company_skills",
|
|
"description": "Create or inspect company skills and synchronize the current agent's skills.",
|
|
"operationIds": ["create_skill", "list_company_skills", "sync_company_skills"]
|
|
},
|
|
{
|
|
"id": "secrets",
|
|
"description": "Inspect secret metadata or use a brokered secret value without exposing plaintext evidence.",
|
|
"operationIds": ["list_secret_metadata", "read_secret_value"]
|
|
},
|
|
{
|
|
"id": "portability_admin",
|
|
"description": "Export portable company state; broad administration remains deferred until split into governed operations.",
|
|
"operationIds": ["export_company", "administer_company"]
|
|
},
|
|
{
|
|
"id": "test_escape_hatch",
|
|
"description": "Controlled skill-test transport only; never product coverage.",
|
|
"operationIds": ["generic_api_request"]
|
|
},
|
|
{
|
|
"id": "api_fallback",
|
|
"description": "Discover and invoke HTTP API operations unsupported by available dedicated tools. Production authority and route authorization remain required.",
|
|
"operationIds": [
|
|
"search_api",
|
|
"call_api"
|
|
]
|
|
}
|
|
],
|
|
"behaviorGroups": [
|
|
{
|
|
"id": "hb",
|
|
"legacyGroup": 1,
|
|
"name": "Heartbeat",
|
|
"owner": "control plane + always tools",
|
|
"operationIds": ["get_task_context"],
|
|
"controlPlaneOperationIds": ["select_work", "enforce_budget"],
|
|
"realSurface": "agent identity, inbox-lite, heartbeat context, budget and active-issue services",
|
|
"mockStateDomains": ["company", "actor", "wake", "task", "budget", "run"],
|
|
"prpEvidence": "runner/session/run context plus bounded task-context tool results",
|
|
"gap": "Production semantic binding is unbound; identity and work selection remain injected/control-plane-owned."
|
|
},
|
|
{
|
|
"id": "co",
|
|
"legacyGroup": 2,
|
|
"name": "Checkout",
|
|
"owner": "control plane",
|
|
"operationIds": [],
|
|
"controlPlaneOperationIds": ["checkout_task"],
|
|
"realSurface": "POST /api/issues/:id/checkout and execution-lock services",
|
|
"mockStateDomains": ["task", "actor", "run", "idempotency", "fault"],
|
|
"prpEvidence": "run preparation and issue-status decision evidence with checkout receipt",
|
|
"gap": "Intentionally no model tool; the production checkout receipt still needs the additive semantic-receipt envelope."
|
|
},
|
|
{
|
|
"id": "st",
|
|
"legacyGroup": 3,
|
|
"name": "Status",
|
|
"owner": "always tools + control-plane arbitration",
|
|
"operationIds": ["answer_status_question", "finish_task", "block_task", "request_review"],
|
|
"controlPlaneOperationIds": ["reconcile_run", "append_audit_record"],
|
|
"realSurface": "issue PATCH, review/liveness policy, and native finalization arbitration",
|
|
"mockStateDomains": ["task", "comments", "interactions", "blockers", "audit", "run"],
|
|
"prpEvidence": "semantic operation receipt, work assessment, issue-status decision, and terminal causality",
|
|
"gap": "Production semantic binding and additive typed operation/conflict receipts remain unimplemented."
|
|
},
|
|
{
|
|
"id": "cm",
|
|
"legacyGroup": 4,
|
|
"name": "Comments",
|
|
"owner": "always tools",
|
|
"operationIds": ["get_task_history", "report_progress"],
|
|
"controlPlaneOperationIds": ["append_audit_record"],
|
|
"realSurface": "issue comment list/get/create routes",
|
|
"mockStateDomains": ["task", "comments", "actor", "idempotency", "audit"],
|
|
"prpEvidence": "bounded read result or idempotent comment-write receipt plus audit reference",
|
|
"gap": "Active-task binding is unbound; cross-task comment mutation is deliberately outside V1."
|
|
},
|
|
{
|
|
"id": "se",
|
|
"legacyGroup": 5,
|
|
"name": "Search",
|
|
"owner": "optional discovery tools",
|
|
"operationIds": ["search_tasks", "list_agents", "get_agent", "list_projects", "list_goals", "list_project_repositories"],
|
|
"controlPlaneOperationIds": [],
|
|
"realSurface": "company issue search and agent/project/goal list/get routes",
|
|
"mockStateDomains": ["company", "task", "actor", "project", "goal"],
|
|
"prpEvidence": "bounded redacted read projections through tool-result item events",
|
|
"gap": "Goal operations remain scenario-only. Project and repository discovery contracts are delivered by the live server authority; they are not implemented by the mock command dispatcher."
|
|
},
|
|
{
|
|
"id": "su",
|
|
"legacyGroup": 6,
|
|
"name": "Subtasks",
|
|
"owner": "optional delegation tools",
|
|
"operationIds": ["create_task"],
|
|
"controlPlaneOperationIds": ["route_wake"],
|
|
"realSurface": "company issue create, child issue, assignment, and wake services",
|
|
"mockStateDomains": ["company", "task", "actor", "blockers", "wake", "audit"],
|
|
"prpEvidence": "company/task state diff, audit reference, and continuation wake evidence",
|
|
"gap": "create_task is production-bound to ordinary active-issue child creation with assignment, dependency-ready wake, company checks, child limits, and durable source-scoped idempotency."
|
|
},
|
|
{
|
|
"id": "bl",
|
|
"legacyGroup": 7,
|
|
"name": "Blockers",
|
|
"owner": "always/optional tools + control plane",
|
|
"operationIds": ["block_task", "set_dependencies"],
|
|
"controlPlaneOperationIds": ["schedule_blocker_wake", "route_wake"],
|
|
"realSurface": "issue relations, blocker projection, liveness validation, and blocker wake services",
|
|
"mockStateDomains": ["task", "blockers", "wake", "actor", "audit", "fault"],
|
|
"prpEvidence": "dependency diff, block receipt, attention routing, and issue-status decision",
|
|
"gap": "set_dependencies is production-bound for the active issue; block_task remains unbound, and cancelled-blocker receipts still need typed additive evidence."
|
|
},
|
|
{
|
|
"id": "dp",
|
|
"legacyGroup": 8,
|
|
"name": "Documents and plans",
|
|
"owner": "always tools; restore optional; destructive lifecycle control-plane-only",
|
|
"operationIds": ["list_documents", "read_document", "list_document_revisions", "write_document"],
|
|
"controlPlaneOperationIds": ["append_audit_record"],
|
|
"realSurface": "issue document list/read/upsert/revision/restore/lock/unlock/delete routes",
|
|
"mockStateDomains": ["task", "documents", "interactions", "idempotency", "audit", "fault"],
|
|
"prpEvidence": "bounded reads and revision-safe write/conflict/denial receipts with revision lineage",
|
|
"gap": "restore_document_revision is an approved optional-tool gap; lock/unlock/delete are intentionally control-plane-only."
|
|
},
|
|
{
|
|
"id": "ix",
|
|
"legacyGroup": 9,
|
|
"name": "Interactions",
|
|
"owner": "always tools + addressed resolver",
|
|
"operationIds": ["request_human_input"],
|
|
"controlPlaneOperationIds": ["route_wake"],
|
|
"realSurface": "issue-thread interaction create/respond/accept/reject/withdraw services",
|
|
"mockStateDomains": ["task", "documents", "interactions", "wake", "actor", "idempotency"],
|
|
"prpEvidence": "interaction proposal/materialization/response/delivery and attention events",
|
|
"gap": "Production binding and semantic resolution receipts are unbound."
|
|
},
|
|
{
|
|
"id": "ap",
|
|
"legacyGroup": 10,
|
|
"name": "Approvals",
|
|
"owner": "optional governance tools + governed approver",
|
|
"operationIds": ["list_approvals", "get_approval", "get_approval_context", "request_approval", "decide_approval", "comment_on_approval"],
|
|
"controlPlaneOperationIds": ["route_wake", "append_audit_record"],
|
|
"realSurface": "company approval, decision, issue-link, comment, and governed-action services",
|
|
"mockStateDomains": ["company", "task", "approvals", "actor", "wake", "audit", "idempotency"],
|
|
"prpEvidence": "governed semantic receipts, audit references, and attention/continuation linkage",
|
|
"gap": "Production binding and additive governed-action receipts are unbound; board-only authority stays outside grants."
|
|
},
|
|
{
|
|
"id": "ar",
|
|
"legacyGroup": 11,
|
|
"name": "Artifacts",
|
|
"owner": "always tools + artifact/work-product services",
|
|
"operationIds": ["register_deliverable"],
|
|
"controlPlaneOperationIds": ["append_audit_record"],
|
|
"realSurface": "attachment upload and issue work-product routes",
|
|
"mockStateDomains": ["task", "artifacts", "workProducts", "workspace", "audit", "idempotency"],
|
|
"prpEvidence": "artifact/work-product reference and durable inspectability receipt; never binary bytes",
|
|
"gap": "Production upload/register composite and additive durable-reference receipt are unbound."
|
|
},
|
|
{
|
|
"id": "er",
|
|
"legacyGroup": 12,
|
|
"name": "Errors and critical rules",
|
|
"owner": "runner/control plane + optional workspace/wake tools",
|
|
"operationIds": ["get_workspace_runtime", "control_workspace_service", "schedule_wake", "inspect_operation_result"],
|
|
"controlPlaneOperationIds": ["release_task", "enforce_budget", "persist_run", "replay_run", "reconcile_run"],
|
|
"realSurface": "workspace runtime, monitor/recovery, budget, run persistence/replay, release, and terminal services",
|
|
"mockStateDomains": ["workspace", "budget", "run", "wake", "audit", "idempotency", "fault"],
|
|
"prpEvidence": "runtime/workspace/attention/run lifecycle, typed denials, replay facts, and terminal causality",
|
|
"gap": "Budget stop reasons and semantic denial/conflict receipts require additive v1 envelopes; inspect_operation_result remains scenario-only."
|
|
},
|
|
{
|
|
"id": "rf",
|
|
"legacyGroup": 13,
|
|
"name": "Reference files",
|
|
"owner": "optional domain tools + test-only escape hatch",
|
|
"operationIds": ["list_cases", "upsert_case", "list_routines", "manage_routine", "create_skill", "list_company_skills", "sync_company_skills", "list_secret_metadata", "read_secret_value", "export_company", "administer_company", "generic_api_request", "search_api", "call_api", "create_project"],
|
|
"controlPlaneOperationIds": ["append_audit_record"],
|
|
"realSurface": "project, case, routine, company-skill, secret, portability, and administration services",
|
|
"mockStateDomains": ["company", "cases", "routines", "skills", "secrets", "audit", "fault"],
|
|
"prpEvidence": "bounded domain projections, redacted broker receipts, company diffs, and audit references",
|
|
"gap": "Project and skill creation and API tools require the live server authority; generic_api_request is test-only and the remaining domain operations are scenario-only. Broad administer_company is deferred and cannot claim product coverage. Production API and paired dedicated-tool regressions are recorded separately in paperclip-evals/evals/runner-api-tools; the legacy scenario count is not evidence of that coverage."
|
|
},
|
|
{
|
|
"id": "mh",
|
|
"legacyGroup": 14,
|
|
"name": "Multi-hop",
|
|
"owner": "composed semantic operations + control-plane continuation",
|
|
"operationIds": ["create_task", "set_dependencies", "request_human_input", "request_approval", "register_deliverable"],
|
|
"controlPlaneOperationIds": ["route_wake", "reconcile_run"],
|
|
"realSurface": "delegation, dependency, interaction, approval, artifact, and terminal orchestration services",
|
|
"mockStateDomains": ["task", "blockers", "interactions", "approvals", "artifacts", "wake", "run", "audit"],
|
|
"prpEvidence": "correlated operation receipts, state diffs, attention hops, work assessment, status decision, and terminal outcome",
|
|
"gap": "No generic transaction tool is allowed; shared mock/real conformance must prove each composed effect."
|
|
},
|
|
{
|
|
"id": "rs",
|
|
"legacyGroup": 15,
|
|
"name": "Restraint and no-call",
|
|
"owner": "policy/exposure layer",
|
|
"operationIds": ["answer_status_question", "read_secret_value", "generic_api_request"],
|
|
"controlPlaneOperationIds": ["enforce_budget"],
|
|
"realSurface": "task-mode, secret-broker, test-scope, pause, and budget policy checks",
|
|
"mockStateDomains": ["actor", "task", "budget", "secrets", "audit", "fault"],
|
|
"prpEvidence": "absence of forbidden effects plus typed policy denial/redaction receipts when a call is attempted",
|
|
"gap": "Typed redaction/authorization receipts need additive v1 evidence; generic_api_request is never a product fallback."
|
|
},
|
|
{
|
|
"id": "wk",
|
|
"legacyGroup": 16,
|
|
"name": "Wake situations",
|
|
"owner": "control plane + always context/history tools",
|
|
"operationIds": ["get_task_context", "get_task_history", "schedule_wake"],
|
|
"controlPlaneOperationIds": ["select_work", "route_wake"],
|
|
"realSurface": "wakeup requests, heartbeat context, comment/interaction/approval/blocker wake routing, and scheduled wake services",
|
|
"mockStateDomains": ["wake", "task", "comments", "interactions", "approvals", "blockers", "run"],
|
|
"prpEvidence": "attention request routing/resolution plus resumed session/run causality",
|
|
"gap": "Production scheduling binding is unbound; control-plane routing remains non-callable."
|
|
}
|
|
],
|
|
"rules": {
|
|
"companyAuthorization": [
|
|
"Every entity read and write is resolved inside the authenticated actor's company; cross-company identifiers fail without disclosing protected facts.",
|
|
"Board actors use active membership and role permissions. Agent writes require a company-scoped run JWT and X-Paperclip-Run-Id; active-task tools cannot accept a caller-selected company or arbitrary task.",
|
|
"Optional tools are omitted unless every required claim, role, and task-mode condition is satisfied. A grant never bypasses approval, budget, pause, execution-lock, interaction-owner, or other governed-action checks."
|
|
],
|
|
"taskModes": [
|
|
"standard permits the full eligible catalog subject to claims and role checks.",
|
|
"ask is answer-only: investigation reads are eligible, while implementation, document mutation, delegation, terminal, and governed writes are absent.",
|
|
"planning permits plan/document/progress/input operations but not delegation or terminal completion; accepting a plan transitions the issue into a fresh standard execution continuation for the exact accepted revision.",
|
|
"skill_test exposes only scenario-admitted tools. generic_api_request additionally requires the explicit test grant and allowlist and never supplies product coverage."
|
|
],
|
|
"redaction": [
|
|
"Tool descriptors declare observable redaction. Secret plaintext may reach only the model-use capsule authorized for a bound secret; it never reaches PRP, logs, artifacts, errors, audit details, or serialized tool results.",
|
|
"Authorization denials reveal stable codes, missing public claims, and remediation only; they do not include protected entity state, credentials, headers, cookies, or another company's policy.",
|
|
"Artifacts carry durable references, hashes, content type, and size on the wire; binary payloads remain in storage transports."
|
|
],
|
|
"idempotency": [
|
|
"Every mutation whose descriptor says required must carry a stable idempotency key. Retrying the same key and equivalent input returns the prior receipt without duplicating side effects.",
|
|
"Reusing a key with different input is an idempotency conflict. Optimistic document writes additionally bind baseRevisionId and return the current revision on conflict.",
|
|
"PRP source event IDs are idempotent, source sequence gaps are evidence, and replay is side-effect free. Replaying a trace cannot repeat control-plane writes."
|
|
],
|
|
"sideEffects": [
|
|
"read operations return bounded projections and do not mutate control-plane state.",
|
|
"task_write and company_write operations emit normalized state diffs and immutable audit references after production authorization succeeds.",
|
|
"governance, workspace_control, secret_read, and admin operations retain their production-specific gates; catalog exposure is necessary but never sufficient authority.",
|
|
"Terminal semantic operations propose intent. The control plane owns checkout, release, budget enforcement, persisted run evidence, replay, wake routing, audit append, and final status arbitration."
|
|
]
|
|
},
|
|
"documentLifecycle": {
|
|
"scope": [
|
|
"Issue documents are active-task working records identified by (activeIssueId, key). Always-present document tools do not accept a company id or arbitrary issue id.",
|
|
"Cross-task document reads require a future explicit optional operation and grant; case documents and future company knowledge are separate resource types.",
|
|
"Locked-document fallback may create a deterministic new key only when lockedDocumentStrategy is create_new_document; the source stays locked and the returned receipt names the redirected key."
|
|
],
|
|
"operations": [
|
|
{"action": "create", "semanticOperation": "write_document", "placement": "always_agent_tool", "contract": "baseRevisionId is null; create revision 1 and return document/revision/audit identity.", "status": "supported contract; production binding unbound"},
|
|
{"action": "read", "semanticOperation": "list_documents / read_document", "placement": "always_agent_tool", "contract": "List metadata or read the current active-task document by stable key.", "status": "supported contract; production binding unbound"},
|
|
{"action": "update", "semanticOperation": "write_document", "placement": "always_agent_tool", "contract": "Require the exact latest baseRevisionId and an idempotency key; append an immutable revision.", "status": "supported contract; production binding unbound"},
|
|
{"action": "revisions", "semanticOperation": "list_document_revisions", "placement": "always_agent_tool", "contract": "Return bounded immutable revision history newest first.", "status": "supported contract; production binding unbound"},
|
|
{"action": "restore", "semanticOperation": "restore_document_revision", "placement": "optional_agent_tool (documents:restore)", "contract": "Validate same-document lineage, reject locked documents, append a new revision, and return source/new revision identity; restoring current is a no-change duplicate.", "status": "approved catalog gap"},
|
|
{"action": "lock", "semanticOperation": "none", "placement": "control_plane_owned", "contract": "Board/administrative lifecycle action; agent writes receive document_locked or use explicit create-new fallback.", "status": "intentionally non-callable"},
|
|
{"action": "unlock", "semanticOperation": "none", "placement": "control_plane_owned", "contract": "Board/administrative lifecycle action; never inferred from a failed write.", "status": "intentionally non-callable"},
|
|
{"action": "delete", "semanticOperation": "none", "placement": "control_plane_owned", "contract": "Destructive audited action; pending targets become stale and the runner never recreates them automatically.", "status": "intentionally non-callable"}
|
|
]
|
|
},
|
|
"legacySemanticTargetDispositions": {
|
|
"injected_actor_context": {"kind": "control_plane", "targets": ["select_work"], "reason": "Identity is launch context, not a model tool."},
|
|
"runner_work_selection": {"kind": "control_plane", "targets": ["select_work"], "reason": "Inbox selection belongs to the control plane."},
|
|
"get_project": {"kind": "folded", "targets": ["list_projects"], "reason": "The bounded discovery operation owns project list/get projection in V1."},
|
|
"wait_for_workspace_service": {"kind": "folded", "targets": ["control_workspace_service"], "reason": "Wait is a bounded action of workspace service control."},
|
|
"get_goal": {"kind": "folded", "targets": ["list_goals"], "reason": "The bounded discovery operation owns goal list/get projection in V1."},
|
|
"semantic_task_disposition": {"kind": "composite", "targets": ["answer_status_question", "finish_task", "block_task", "request_review"], "reason": "Generic issue PATCH is replaced by intent-specific terminal/status operations."},
|
|
"atomic_checkout": {"kind": "control_plane", "targets": ["checkout_task"], "reason": "Checkout is an atomic control-plane transaction."},
|
|
"runtime_release": {"kind": "control_plane", "targets": ["release_task"], "reason": "Release is runner/control-plane cleanup."},
|
|
"restore_document_revision": {"kind": "known_gap", "targets": [], "reason": "Approved optional documents:restore operation is not yet in the canonical catalog."},
|
|
"link_approval": {"kind": "folded", "targets": ["request_approval", "get_task_context"], "reason": "Issue linkage is part of approval request/context composites."},
|
|
"unlink_approval": {"kind": "control_plane", "targets": ["append_audit_record"], "reason": "No standalone agent unlink tool is approved in V1."},
|
|
"test_only_api_escape_hatch": {"kind": "folded", "targets": ["generic_api_request"], "reason": "Compatibility alias for the test-only escape hatch."}
|
|
}
|
|
}
|