Files
PaperClipAI/packages
Dotta 3ba0e7f64f feat(runner): add durable semantic tool bridge (#12378)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The runner package has a reviewed semantic action catalog and
dispatcher
> - The Rust runner process needs the same fail-closed authorization
boundary
> - Provider calls must remain correlated and idempotent across durable
recovery
> - Input and result values must satisfy the authorized operation
schemas
> - This pull request adds a package-local durable semantic tool bridge
> - It does not advertise tools to Codex or enable the Paperclip Runner
adapter

## Linked Issues or Issue Description

**Subsystem affected**

`packages/paperclip-runner/runner` semantic tool authorization and
correlation.

**Problem or motivation**

The Rust runner needs a durable representation of the run-scoped tools
that the control plane authorizes. It must reject unknown operations,
catalog drift, invalid values, and conflicting duplicate calls or
results before a provider integration can use those tools.

**Proposed solution**

Add a serialized provider tool bridge. Validate the authorized catalog
and its JSON Schemas. Validate each call and result. Keep pending and
completed identities so retries are idempotent and conflicts fail
closed.

**Alternatives considered**

Trusting provider arguments would bypass the run-scoped catalog.
Validating only in TypeScript would leave the Rust process without a
recovery-safe authorization boundary. Adding provider behavior in this
pull request would make the review unit too broad.

**Roadmap alignment**

This adds a package-local safety boundary for the Codex-first runner
path. It does not enable a new adapter or change an existing direct
adapter path.

## What Changed

- Added the versioned authorized-tool, pending-call, and result
contracts.
- Added canonical SHA-256 catalog binding and drift rejection.
- Added JSON Schema compilation and input and response validation.
- Added duplicate-call and duplicate-result idempotency with conflict
rejection.
- Added bounds for catalogs, schemas, values, and retained call
identities.
- Added the Rust `jsonschema` dependency and its Cargo lock entries.
- Added focused tests for authorization, recovery, envelopes, bounds,
and conflicts.

## Verification

- `cargo fmt --manifest-path packages/paperclip-runner/runner/Cargo.toml
--all -- --check`
- `cargo test --manifest-path
packages/paperclip-runner/runner/Cargo.toml -p paperclip-runner-core`
(64 tests)
- `cargo clippy --manifest-path
packages/paperclip-runner/runner/Cargo.toml -p paperclip-runner-core
--all-targets -- -D warnings -A clippy::manual_is_multiple_of -A
clippy::filter_map_bool_then`
- `pnpm -r typecheck`
- `pnpm build`
- The repository test runner also reached unrelated server worktree
suites. Those suites fail on the current macOS worktree with database
deadlocks and filesystem fixture assumptions. This pull request does not
change those files. The applicable GitHub checks remain the handoff
authority.

## Risks

The main risks are accepting a tool that the run did not authorize and
replaying a conflicting provider result. The bridge validates the
catalog, operation identity, JSON Schema, call identity, and result
identity before it changes durable state. The new Cargo dependency is
package-local. This pull request changes no GitHub workflow and no pnpm
lockfile.

## Model Used

OpenAI Codex with GPT-5 and repository tool use.

## 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
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-08-30 03:27:37 -05:00
..