Files
PaperClipAI/packages/paperclip-runner/SEMANTIC_ACTIONS.md
DottaandPaperclip 42b8f7ab2f feat(runner): authorize semantic tool dispatch (#12126)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The runner package defines a provider-neutral protocol and semantic
action catalog.
> - Catalog membership alone must not grant access to an action.
> - Each run needs current company, actor, task, claim, mode, and
application-binding authority.
> - Mutating actions also need safe retry behavior and durable receipts.
> - This pull request adds a package-local authority and dispatch layer.
> - The benefit is a small and testable trust boundary before server
integration lands.

## Linked Issues or Issue Description

Refs #11962

This pull request replaces one bounded part of the archived large runner
change.

## What Changed

- Add run-scoped tool projection and optional tool discovery.
- Require an explicit application binding before an action is visible.
- Intersect actor claims with claims delegated to the run.
- Recheck company, actor, task, mode, state, role, claim, and policy
authority before each call.
- Validate action input and output with the canonical catalog schemas.
- Redact protected values and keep raw tool content out of semantic
receipts.
- Require atomic idempotency claims for mutating actions.
- Replay exact completed retries and reject changed or concurrent
retries.
- Recover a durable completed receipt if the primary receipt commit
fails, without re-executing the mutation.
- Add bounded authorization records and PRP semantic input and result
receipts.
- Document that this change adds no server binding or production tool
installation.

## Verification

- `pnpm --filter @paperclipai/paperclip-runner check:all`
- `pnpm -r typecheck`
- `pnpm check:token-gates`
- `pnpm build`
- 60 package TypeScript tests pass.
- 56 Rust unit and integration tests pass.
- Protocol, replay, and cross-language conformance checks pass.
- `pnpm test:run` completed with 4,684 passing and 19 skipped tests. It
reproduced 32 local baseline failures across 9 unchanged server files;
all corresponding hosted test shards pass.
- Every applicable GitHub Actions gate passes. The Storybook job skipped
because this PR has no UI changes.
- Socket and Snyk pass with no findings. Superagent completed neutral
with zero annotations because its external sandbox did not start within
120 seconds.
- Greptile is 5/5 with no unresolved actionable comments.
- The diff changes 11 files.

## Risks

The main risk is an authorization or idempotency error at the tool
boundary. The dispatcher fails closed for malformed authority,
unavailable receipt storage, stale authority, unauthorized actions,
protected input, invalid binding output, and unrecoverable receipt
completion. The receipt store must recover a completed mutation outcome
idempotently if its primary commit fails; otherwise the claim remains
reserved for operator recovery rather than allowing automated
re-execution. Unbound actions are absent. No server or provider installs
these tools in this change. Existing adapters and application behavior
do not change.

## Model Used

OpenAI Codex with GPT-5. Agentic coding mode used repository tools, code
execution, and automated tests.

## 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 the affected tests locally and they pass; full-suite
baseline exceptions are documented above
- [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>
2026-08-24 17:28:54 -05:00

2.3 KiB

Semantic action catalog

The package exports a versioned, provider-neutral catalog for the first Codex runner slice. Each declaration has a stable operation ID, placement metadata, required claims, supported task modes, an effect class, and JSON Schema input and output contracts.

The catalog is descriptive. Importing it or finding an operation in it does not grant permission to show or call that operation. A run-scoped dispatcher can project only actions that have current actor, task, company, claim, mode, and application-binding authority. It rechecks that authority before each call. The package still adds no application binding, credential, server route, or Codex tool installation. Until a later server integration supplies those bindings, Codex receives no dynamic Paperclip tools.

The initial catalog excludes scenario-only and lab operations, other-provider extensions, and a generic API escape hatch. Those additions need their own reviewed schemas and authority boundaries.

Public API

import {
  PAPERCLIP_SEMANTIC_ACTION_CATALOG,
  paperclipSemanticAction,
} from "@paperclipai/paperclip-runner";

const writeDocument = paperclipSemanticAction("write_document");

PAPERCLIP_SEMANTIC_ACTION_CATALOG and every nested declaration are frozen. paperclipSemanticAction returns undefined for unknown operation IDs.

Run-scoped authority

PaperclipSemanticDispatcher accepts a current-context provider and an explicit list of application bindings. Unbound actions are absent. Actor claims and run-delegated claims are intersected. Optional discovery returns only bound actions that pass the same authorization check. Mutation actions also require an atomic idempotency store. The store must provide an idempotent recovery path for a mutation that succeeds before its primary receipt commit fails. Raw tool content never enters semantic receipts; receipts contain a digest and allowlisted references only.

Generated inventory

generated/semantic-action-catalog.json is a deterministic projection of the runtime declarations. Change the TypeScript source, then run:

pnpm --filter @paperclipai/paperclip-runner generate:semantic-action-catalog

The package build and catalog tests compare the checked-in inventory byte for byte. Do not edit the generated file directly.