## 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>
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.